Fluent Nhibernate - 保存没有引用的子对象

时间:2013-06-06 15:31:29

标签: fluent-nhibernate fluent-nhibernate-mapping

我的解决方案中有以下地图

public BlogMap() {
    Table("Blogs");
    LazyLoad();
    Id(x => x.BlogId).GeneratedBy.Identity().Column("BlogId");
    Map(x => x.BlogName).Column("BlogName").Not.Nullable();
    Map(x => x.BlogCreateDate).Column("BlogCreateDate");
    Map(x => x.PostCount).Column("PostCount");
    HasMany(x => x.BlogPosts).KeyColumn("BlogId");
}

public BlogPostMap() {
    Table("BlogPosts");
    LazyLoad();
    CompositeId().KeyProperty(x => x.PostId, "PostId").KeyProperty(x => x.BlogId,`enter code here` "BlogId");
    References(x => x.Blog).Column("BlogId");
    Map(x => x.PostText).Column("PostText");
    Map(x => x.CreateDate).Column("CreateDate");
}

一个博客可能包含许多BlogPosts

我正在尝试创建一个新的BlogPost并将其保存到数据库中。以下是我尝试这样做的方法,但它不起作用。

BlogPost newbgPost = new BlogPost();
newbgPost.BlogId = currMasterBlogId;
newbgPost.CreateDate = DateTime.Now;
newbgPost.PostText = newPostText;
newbgPost.PostId = newPostId+1;

repBlogPost.Save(newbgPost);

如果我在BlogPost地图中删除References(x => x.Blog).Column("BlogId");,则上述代码有效。

据我所知,新的BlogPost正在博客中寻找参考,我是否可以使用newbgPost.BlogId = currMasterBlogId;来实现,这基本上是我希望BlogPost引用的BlogId。

以下是BlogPost类

public class BlogPost {
        public virtual int PostId { get; set; }
        public virtual int BlogId { get; set; }
        public virtual Blog Blog { get; set; }
        public virtual string PostText { get; set; }
        public virtual System.Nullable<System.DateTime> CreateDate { get; set; }
        #region NHibernate Composite Key Requirements
        public override bool Equals(object obj) {
            if (obj == null) return false;
            var t = obj as BlogPost;
            if (t == null) return false;
            if (PostId == t.PostId && BlogId == t.BlogId)
                return true;

            return false;
        }
        public override int GetHashCode() {
            int hash = 13;
            hash += PostId.GetHashCode();
            hash += BlogId.GetHashCode();

            return hash;
        }
        #endregion
    }

博客课程:

  public class Blog {
        public Blog() {
            BlogPosts = new List<BlogPost>();
        }
        public virtual int BlogId { get; set; }
        public virtual string BlogName { get; set; }
        public virtual System.Nullable<System.DateTime> BlogCreateDate { get; set; }
        public virtual System.Nullable<int> PostCount { get; set; }
        public virtual IList<BlogPost> BlogPosts { get; set; }
    }

2 个答案:

答案 0 :(得分:0)

每当您尝试在父级和子级之间创建关系时,必须加载父对象,而不是设置管理关系的字段的Id属性。

更改您的代码,如下所示,以便保留新的博客帖子:

BlogPost newbgPost = new BlogPost();
newbgPost.Blog = nhSession.Load<Blog>(currMasterBlogId);
newbgPost.CreateDate = DateTime.Now;
newbgPost.PostText = newPostText;
newbgPost.PostId = newPostId+1;

repBlogPost.Save(newbgPost);

nHibernate会处理关系并相应地更新BlogId字段 - 您无需设置该属性。

您还需要更改映射,以便通过将property方法更改为reference,使CompositeId由PostId KeyProperty和博客KeyReference组成如下所示:

public BlogPostMap() {
    Table("BlogPosts");
    LazyLoad();
    Map(x => x.PostId);
    Map(x => x.BlogId).ReadOnly();
    CompositeId().KeyProperty(x => x.PostId).KeyReference(x => x.Blog);
    References(x => x.Blog).Column("BlogId");
    Map(x => x.PostText).Column("PostText");
    Map(x => x.CreateDate).Column("CreateDate");
}

答案 1 :(得分:0)

只是说明你不能在CompositeId()和其他映射之间进行重复映射,即Map(),References()。

在复合ID中包含属性后,它已经映射。所以在CSL的回答中,您仍然需要删除2行代码:

Map(x => x.PostId);
References(x => x.Blog).Column("BlogId");

结果应如下所示:

public BlogPostMap() {
    Table("BlogPosts");
    LazyLoad();
    Map(x => x.BlogId).ReadOnly();
    CompositeId().KeyProperty(x => x.PostId).KeyReference(x => x.Blog);
    Map(x => x.PostText).Column("PostText");
    Map(x => x.CreateDate).Column("CreateDate");
}

假设映射的其余部分是正确的,那么应该可以工作。