NHibernate - 保存简单的父子关系会生成带有指定id的不必要的选择

时间:2010-06-02 07:27:42

标签: nhibernate nhibernate-mapping

实体:

public class Parent
{
    virtual public long Id { get; set; }
    virtual public string Description { get; set; }

    virtual public ICollection<Child> Children { get; set; }
}

public class Child
{
    virtual public long Id { get; set; }
    virtual public string Description { get; set; }

    virtual public Parent Parent { get; set; }
}

映射:

public class ParentMap : ClassMap<Parent>
{
    public ParentMap()
    {
        Id(x => x.Id).GeneratedBy.Assigned();

        Map(x => x.Description);

        HasMany(x => x.Children)
            .AsSet()
            .Inverse()
            .Cascade.AllDeleteOrphan();
    }
}

public class ChildMap : ClassMap<Child>
{
    public ChildMap()
    {
        Id(x => x.Id).GeneratedBy.Assigned();

        Map(x => x.Description);

        References(x => x.Parent)
            .Not.Nullable()
            .Cascade.All();
    }
}

        using (var session = sessionFactory.OpenSession())
        using (var transaction = session.BeginTransaction())
        {
            var parent = new Parent { Id = 1 };

            parent.Children = new HashSet<Child>();

            var child1 = new Child { Id = 2, Parent = parent };
            var child2 = new Child { Id = 3, Parent = parent };

            parent.Children.Add(child1);
            parent.Children.Add(child2);

            session.Save(parent);

            transaction.Commit();
        }

此代码生成以下sql

NHibernate: SELECT child_.Id, child_.Description as Descript2_0_, child_.Parent_id as Parent3_0_ FROM [Child] child_ WHERE child_.Id=@p0;@p0 = 2 [Type: Int64 (0)]
NHibernate: SELECT child_.Id, child_.Description as Descript2_0_, child_.Parent_id as Parent3_0_ FROM [Child] child_ WHERE child_.Id=@p0;@p0 = 3 [Type: Int64 (0)]
NHibernate: INSERT INTO [Parent] (Description, Id) VALUES (@p0, @p1);@p0 = NULL[Type: String (4000)], @p1 = 1 [Type: Int64 (0)]
NHibernate: INSERT INTO [Child] (Description, Parent_id, Id) VALUES (@p0, @p1, @p2);@p0 = NULL [Type: String (4000)], @p1 = 1 [Type: Int64 (0)], @p2 = 2 [Type:Int64 (0)]
NHibernate: INSERT INTO [Child] (Description, Parent_id, Id) VALUES (@p0, @p1, @p2);@p0 = NULL [Type: String (4000)], @p1 = 1 [Type: Int64 (0)], @p2 = 3 [Type:Int64 (0)]

为什么会生成这两个选项?如何删除它?

1 个答案:

答案 0 :(得分:1)

选择在那里是因为您明确设置了ID。 NHibernate不知道是否要更新或更新,因此必须查明它们是否存在于数据库中。如果他们这样做,它将更新,如果没有(如你的情况),它将插入。