【问题标题】:Many to Many Nhibernate - Duplicate records and no insert多对多 Nhibernate - 重复记录且无插入
【发布时间】:2015-10-18 10:18:42
【问题描述】:

我有三个与下面的 nhibernate 地图存在多对多关系的表。我的对象也在下面。一个投资组合项目可以有许多标签。我遇到的问题是

1) 更新保存另一个标签,即使名称与上次相同。因此,当标签相同时,重复记录会被插入标签中。因此,例如,如果一个投资组合对象的标签是 abc,则添加该标签的下一个投资组合项目应引用此记录,而不是重新插入 abc。我认为这是因为标签映射中的 id 列。不过,Nhibernate 需要一个 id。

2) Create 不会在连接表中添加记录。连接表中的记录仅在更新时添加。

领域对象

public class Portfolio {
    public Portfolio() {
        PortfolioImage = new List<Portfolioimage>();
        Tag = new List<Tag>();
    }
    public virtual int PortfolioId { get; set; }
    public virtual string AliasTitle { get; set; }
    public virtual string MetaDescription { get; set; }
    public virtual string Title { get; set; }
    public virtual string Client { get; set; }
    public virtual string Summary { get; set; }
    public virtual string Url { get; set; }
    public virtual string MainImage { get; set; }
    public virtual string TitleAlt { get; set; }
    public virtual string Description { get; set; }
    public virtual IList<Portfolioimage> PortfolioImage { get; set; }
    public virtual IList<Tag> Tag { get; set; }
}

public class Portfoliotag {
    public virtual int Id { get; set; }
    public virtual Portfolio Portfolio { get; set; }
    public virtual Tag Tag { get; set; }
}

public class Tag {
    public Tag() {
        Portfolio = new List<Portfolio>();
    }
    public virtual int TagId { get; set; }
    public virtual string TagVal { get; set; }
    public virtual IList<Portfolio> Portfolio { get; set; }
}

地图

     public class PortfolioMap : ClassMap<Portfolio> {

        public PortfolioMap() {
            Table("Portfolio");
            LazyLoad();
            Id(x => x.PortfolioId).GeneratedBy.Identity().Column("PortfolioId");
            Map(x => x.AliasTitle).Column("AliasTitle").Not.Nullable();
            Map(x => x.MetaDescription).Column("MetaDescription").Not.Nullable();
            Map(x => x.Title).Column("Title").Not.Nullable();
            Map(x => x.Client).Column("Client").Not.Nullable();
            Map(x => x.Summary).Column("Summary").Not.Nullable();
            Map(x => x.Url).Column("Url");
            Map(x => x.MainImage).Column("MainImage");
            Map(x => x.TitleAlt).Column("TitleAlt");
            Map(x => x.Description).Column("Description").Not.Nullable();
            HasMany(x => x.PortfolioImage).KeyColumn("PortfolioId").Inverse();
            HasManyToMany(x => x.Tag).Table("PortfolioTag").ParentKeyColumn("PortfolioId").ChildKeyColumn("TagId").LazyLoad().Cascade.All().Fetch.Join();
        }
    }

        public class PortfoliotagMap : ClassMap<Portfoliotag> {

        public PortfoliotagMap() {
            Table("PortfolioTag");
            LazyLoad();
            Id(x => x.Id).GeneratedBy.Identity().Column("Id");
            References(x => x.Portfolio).Not.Nullable().Cascade.SaveUpdate().Column("PortfolioId");
            References(x => x.Tag).Not.Nullable().Cascade.SaveUpdate().Column("TagId");
        }
    }

 public class TagMap : ClassMap<Tag> {

        public TagMap() {
            Table("Tag");
            LazyLoad();
            Id(x => x.TagId).GeneratedBy.Identity().Column("TagId");
            Map(x => x.TagVal).Column("Tag").Not.Nullable();
            //HasMany(x => x.PortfolioTag).KeyColumn("TagId");
           // HasMany(x => x.PortfolioTag).Cascade.AllDeleteOrphan().Inverse().Fetch.Join().KeyColumn("TagId");
            HasManyToMany(x => x.Portfolio).Table("PortfolioTag").ParentKeyColumn("PortfolioId").ChildKeyColumn("TagId").LazyLoad().Inverse().Cascade.AllDeleteOrphan();
        }
    }

【问题讨论】:

  • 之前的映射是正确的。我会避免多对多...
  • 之前的映射
  • 这不允许我保存标签。在投资组合标签上,我是否需要将投资组合项目添加到投资组合标签。似乎有这样做的标准方法。可能会迁移到实体框架
  • 当您发布问题时,请排除不属于问题的所有属性和映射。代码量让我不知所措,几乎跳过了这个问题。其他人可能会跳得更快。

标签: nhibernate fluent-nhibernate


【解决方案1】:

给定的类

public class Portfolio
 {
    public Portfolio()
    {
        Tag = new List<Tag>();
    }
    public virtual int PortfolioId { get; protected set; }
    public virtual IList<Tag> Tag { get; protected set; }
}

public class Tag
{
    public virtual int TagId { get; set; }
    public virtual string Name { get; set; }
}

这个映射就足够了

public class PortfolioMap : ClassMap<Portfolio>
{
    public PortfolioMap()
    {
        Id(x => x.PortfolioId).GeneratedBy.Identity().Column("PortfolioId");

        HasManyToMany(x => x.Tag)
            .Table("PortfolioTag")
            .ParentKeyColumn("PortfolioId")
            .ChildKeyColumn("TagId")
            .Cascade.All()
            .Fetch.Join();
    }
}

必须在代码中处理分配现有标签,该代码可以比任何框架的自动查询更有效地缓存或查询涉及的标签。

更新:

对我有用的示例用法

public void Save(int portfolioId, IEnumerable<string> tagnames)
{
    using (var tx = session.BeginTransaction())
    {
        var tags = Session.QueryOver<Tag>().WhereProperty(x => x.Name).In(tagnames).List();

        var portfolio = session.Get<Portfolio>(portfolioId);
        portfolio.Tags.Clear();
        portfolio.Tags.AddRange(tags);
        tx.Commit();
    }
}

【讨论】:

  • 嗨,我添加了这个修改。仍在发生的一件事是中间连接表没有在插入时添加记录。它适用于更新。同样在更新右表时,即再次复制标签而不是引用现有记录
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-10-01
  • 1970-01-01
  • 2020-05-19
  • 2019-12-18
  • 2018-07-28
相关资源
最近更新 更多