【问题标题】:Nhibernate OneToMany (Inverse) Sets FK to 0, why?Nhibernate OneToMany (Inverse) 将 FK 设置为 0,为什么?
【发布时间】:2014-12-22 16:03:43
【问题描述】:

我的 nHibernate Mapping-By-Code 有问题。

Content 有来自表 Content_Texts 的多个条目,由 FK 列“ContentId”引用。

如果我在集合中添加一个带有一个 Text 的新 ContentEntry,我会执行第一个对 Content Table 的查询,但第二个(对 Content_Texts)失败,因为 NHibernate 正在尝试使用 ContentId = 0,在内容表中肯定不存在。

这是我的内容表映射:

public class ContentMap : ClassMapping<TContent>
{
    #region Constructors

    public ContentMap()
    {
        Table("nfcms_Content");
        Schema("dbo");
        Lazy(false);
        Id<int>(x => x.Id, map => {

            map.Generator(Generators.Identity);

        });
        //Property(x => x.Id, map => map.NotNullable(true));

        Property(x => x.Cid, map =>
        {
            map.NotNullable(false);

        });
        Property(x => x.CreatorPKID, map => map.NotNullable(false));
        Property(x => x.Locked, map => {

            map.NotNullable(true);

            map.Type(NHibernateUtil.Boolean);

        });
        Property(x => x.RatingGroupID);
        Property(x => x.CDate);

        Property(x => x.ContentType, map => map.NotNullable(true));

        Property(x => x.ContentRef);
        Property(x => x.CreatorSpecialName);

        Bag(x => x.Texts, mapping =>
        {
            mapping.Lazy(CollectionLazy.NoLazy);
            mapping.Key(k =>
            {
                k.Column("ContentId");
                
            });
            mapping.Inverse(true);
            mapping.Cascade(Cascade.All);
            
            mapping.Fetch(CollectionFetchMode.Select);
           
        },
           r => r.OneToMany());

        ManyToOne(x => x.User, m =>
        {

            m.Column(c => c.Name("CreatorPKID"));
            m.Fetch(FetchKind.Select);
            m.Cascade(Cascade.None);
            m.Insert(false);
            m.Update(false);
            m.Lazy(LazyRelation.NoLazy);

        });

        ManyToOne(x => x.Category, m =>
        {

            m.Column(c => c.Name("CID"));
            m.Fetch(FetchKind.Select);
            m.Cascade(Cascade.None);
            m.Insert(false);
            m.Update(false);
            m.Lazy(LazyRelation.NoLazy);

        });

        //OneToOne(x => x.Category, map =>
        //{
        //    map.PropertyReference(
        //    map.Column("CID");
        //    map.NotFound(NotFoundMode.Ignore);
        //    map.Cascade(Cascade.None);
        //});

        //ManyToOne(x => x.User, map =>
        //{
        //    map.PropertyRef("PKID");
        //    map.Column("CreatorPKID");

        //    map.Cascade(Cascade.None);
        //});
    }

    #endregion Constructors
}

这里是 Content_Text 表

public class ContentTextMap : ClassMapping<Persistence.Domain.ContentText>
{
    #region Constructors

    public ContentTextMap()
    {
        Table(Ren.CMS.CORE.Config.RenConfig.DB.Prefix +"Content_Text");
        Schema("dbo");
        Lazy(false);
        Id<int>(x => x.Id, map => {

            map.Generator(Generators.Identity);

        });
        Property(x => x.ContentId, map => map.NotNullable(true));
        Property(x => x.LangCode, map => map.NotNullable(true));

        //Property(x => x.Id, map => map.NotNullable(true));
        Property(x => x.Title, map => map.NotNullable(true));

        Property(x => x.Seoname);

        Property(x => x.MetaKeyWords);
        Property(x => x.MetaDescription);
        Property(x => x.PreviewText);

        Property(x => x.LongText, x => x.Type(NHibernateUtil.StringClob));


        //OneToOne(x => x.Category, map =>
        //{
        //    map.PropertyReference(
        //    map.Column("CID");
        //    map.NotFound(NotFoundMode.Ignore);
        //    map.Cascade(Cascade.None);
        //});

        //ManyToOne(x => x.User, map =>
        //{
        //    map.PropertyRef("PKID");
        //    map.Column("CreatorPKID");

        //    map.Cascade(Cascade.None);
        //});
    }

    #endregion Constructors
}

这是 NHibernate 执行的查询:

NHibernate:插入到 dbo.nfcms_Content(CDate、Cid、ContentRef、ContentType、CreatorPKID、CreatorSpecialName、Locked、RatingGroupID)值(@p0、@p1、@p2、@p3、@p4、@p5、@p6、 @p7);选择 SCOPE_IDENTITY();@p0 = 27.10.2014 13:51:58 [类型:日期时间 (0)],@p1 = NULL [类型:Guid (0)],@p2 = 0 [类型:Int32 (0)] , @p3 = 'eNews' [类型:字符串 (4000)],@p4 = NULL [类型:Guid (0)],@p5 = '' [类型:字符串 (4000)],@p6 = False [类型: Boolean (0)], @p7 = 0 [类型:Int32 (0)]

NHibernate:插入到 dbo.nfcms_Content_Text(ContentId、LangCode、LongText、 MetaDescription、MetaKeyWords、PreviewText、Seoname、标题)值(@p0、@p1、@p2、@p3、@p4、@p5、@p6、@p7);选择 SCOPE_IDENTITY();@p0 = 0 [类型:Int32 (0)],@p1 = 'de-DE' [类型:字符串 (4000)],@p2 = '测试'[类型:字符串 (1073741823)], @p3 = 'test' [类型:字符串 (4000)],@p4 = 'test' [类型:字符串 (4000)],@p5 = 'test' [类型:字符串 (4000)],@p6 = 'TEST123455 ' [类型:字符串(4000)],@p7 = 'TEST' [类型:字符串(4000)]

谁能告诉我怎么了?我找了又找,没有找到解决办法……

【问题讨论】:

    标签: c# nhibernate nhibernate-mapping mapping-by-code


    【解决方案1】:

    因为我们确实将 one-to-many 关系端映射为 Bag 并使用 inverse 设置 (这绝对可以) 如下所示:

    public ContentMap()
    {
        ...
        Bag(x => x.Texts, mapping =>
        {
            mapping.Lazy(CollectionLazy.NoLazy);
            mapping.Key(k =>
            {
                k.Column("ContentId");
    
            });
            ...
    

    我们也需要另一端——多对一。在我们的例子中,它必须由参考 Content 表示(也可以表示为只读的int ContentId 值)

    public ContentTextMap()
    {
        ManyToOne(x => x.Content, "ContentId");
        Property(x => x.ContentId, map => {
            map.Column("ContentId");
            map.Update(true);
            map.Insert(true);
            map.NotNullable(true)
        });
        ...
    

    期待像这样的POCO

    public class Content
    {
       public virtual IList<ContentText> Texts { get; set; }
       ...
    
    public class ContentText
    {
       public virtual Content Content { get; set; }
       public virtual int ContentId { get; set; }
       ...
    

    这一定是赋值(两端都要赋值)

    var content = ...;
    var contentText = ...;
    content.Texts.Add(contentText);// both ends must be assigned
    contentText.Content = content; // both ends must be assigned
    

    【讨论】:

    • 很高兴看到这一点!享受 NHibernate,令人惊叹的工具 ;)
    猜你喜欢
    • 2019-04-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-09-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多