1

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

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

一个博客可能包含许多博客帖子

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

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

repBlogPost.Save(newbgPost);

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

我知道新的 BlogPost 正在寻找 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; }
    }
4

2 回答 2

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相应地更新字段 - 您不需要设置该属性。

您还需要更改映射,以便 CompositeId 由 PostIdproperty和 Blog组成,方法是referenceKeyProperty方法更改为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");
}
于 2013-06-06T20:48:46.017 回答
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");
}

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

于 2013-12-09T14:41:03.157 回答