多对多Nhibernate - 重复记录并且没有插入

时间:2015-10-18 10:18:42

标签: nhibernate fluent-nhibernate

我和下面的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();
        }
    }

1 个答案:

答案 0 :(得分:0)

给出了课程

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();
    }
}