流利的Nhibernate将child.parentid = parentId保存在新的父母&儿童

时间:2013-12-13 20:59:22

标签: c# nhibernate fluent-nhibernate

我正在尝试保存新的父项&新子项到遗留数据库

我的数据很好,当我保存它时,父母和孩子都可以保存。但是Child的SillyNameParentId始终为0

表格结构我无法改变所以我必须弄清楚如何使这项工作。

这是SQL生成的

  

NHibernate:INSERT INTO SillyNameParent(描述,活动)VALUES   (@ p0,@ p1);选择SCOPE_IDENTITY(); @ p0 ='测试'[类型:字符串   (1073741823)],@ p1 = True [Type:Boolean(0)] NHibernate:INSERT INTO   SillyChild(SillyNameCategoryId,sillyNameParentid)VALUES(@ p0,@ p1);   选择SCOPE_IDENTITY(); @ p0 = 0 [类型:Int32(0)],@ p1 = 1 [类型:   Int32(0)]

最终我希望@ p1设置为SillyNameParentId / Parentid

表:

SillyNameParent
    Column PK-IsIdentity: ParentId
    Column varchar(255): Description
    Column bit: Active

SillyChild //I'm a lookup table 
    Column int IsIdentity: Id
    Column int PK: SillyNameParentId
    Column int PK: SillyNameCategoryID

模型:

public class SillyNameParent: Entity
{
    public SillyNameParent()
    {
        Children= new List<SillyChild>();
    }
    public virtual string AreaOfConcernDesc { get; set; }
    public virtual bool Active { get; set; }
    public virtual IList<SillyChild> Children{ get; set; }
}

public class SillyChild: Entity
{
    public virtual int SillyNameParentId { get; set; }
    public virtual int SillyNameCategoryId{ get; set; }
    public virtual SillyNameParent Parent { get; set; }

}

MAPS:

public class SillyNameParentMap : IAutoMappingOverride<SillyNameParent>
{
    public void Override(AutoMapping<SillyNameParent> mapping)
    {
        mapping.Table("SillyNameParent");
        mapping.Id(x => x.Id).Column("ParentId").GeneratedBy.Identity();
        mapping.Map(x => x.Description).Not.Nullable();
        mapping.Map(x => x.Active).Nullable();
        mapping.HasMany(x => x.children)
            .Cascade.All()
            .KeyColumn("SillyNameParentId")
            .Not
            .LazyLoad();
    }
}

public class SillyChildMap: IAutoMappingOverride<SillyChild>
{
    public void Override(AutoMapping<SillyChild> mapping)
    {
        mapping.Table("SillyChild");
        mapping.Id(x => x.Id).Column("Id").GeneratedBy.Identity();
        mapping.Map(x => x.SillyNameParentId).Not.Nullable();
        mapping.Map(x => x.SillyNameCategoryId).Not.Nullable();
        mapping.HasOne(x => x.Parent).ForeignKey("SillyNameParentId");
    }
}

2 个答案:

答案 0 :(得分:3)

我会说,你几乎就在那里。只是映射父/子应该是这样的:

SillyNameParentMap:

public void Override(AutoMapping<SillyNameParent> mapping)
{
    ...
    mapping.HasMany(x => x.Children)
        .Cascade.All()
        .KeyColumn("SillyNameParentId")
        .Inverse() // this is the way how to manage insertions
        .Not
        .LazyLoad();   

SillyChildMap:

public void Override(AutoMapping<SillyChild> mapping)
{
    ...
    mapping.References(x => x.Parent)
       .Column("SillyNameParentId");

这种映射最终会正确插入,就像这样:

var parent = new SillyNameParent();
parent... // set properties

var child = new SillyChild();
child... // set properties

parent.Children.Add(child); // parent knows about child
child.Parent = parent; // always do set the relation both ways

sillyService.SaveSillyParent(snp)

编辑:选择2问题

例外情况是双列映射。在INSERT或UPDATE的情况下这是一个问题。但是使用NHibernate,我们可以轻松解决它:

mapping.Map(x => x.SillyNameParentId)
    .Not.Nullable()
    .Not.Insert()
    .Not.Update();
mapping.References(x => x.Parent)
    .Column("SillyNameParentId");

所以,现在我们已经映射了两个属性(引用Parent和它的int表示)。只有引用将用于INSERT,UPDATE。但两者都可以用于Select,Filter / Where和Order by ...

答案 1 :(得分:1)

这是一个解决方法...因为DB正在设置身份我猜我需要在保存孩子之前保存父母。必须有一个更好的方法,但这是我提出的

 public T SaveReturnEntity(T entity)
    {
        try
        {
            this.Session.Save(entity);
        }
        catch
        {
            if (this.Session.IsOpen)
            {
                this.Session.Close();
            }

            throw;
        }

        this.Session.Flush();
        return entity;
    }



 return _sillyParent.SaveReturnEntity(sillyNameParent) != null;


 [Test]
    public void Save_sillyParent()
    {
        var sillyService = ServiceMiniMart.CreateSillyParent();

        var filter = new sillyQueryFilter();
        {
            CategoryId = 1
        };      
        var snp= new SillyNameParent
            {
                Active = true,
                Description= "Test"
            };
        if (sillyService.SaveSillyParent(snp))
        {
           snp.Category = new List<SillyChild>
               {
                   new SillyChild
                       {
                           SillyNameParentId= snp.Id,
                           SillyNameCategoryId= filter.CategoryId.Value,
                           Parent = snp
                       }
               };
        }


       var a =  sillyService.SaveSillyParent(snp);
    }