Cra*_*lla 5 nhibernate nhibernate-mapping fluent-nhibernate
当我尝试在具有一对多关系的任何表上执行ISession.Delete时,我收到了NHibernate的错误.
NHibernate试图将子表中的父表的外键设置为null,而不是仅删除子表行.
这是我的域名:
public class Parent
{
    public Parent()
    {
        _children = new List<Child>();
    }
    public int Id { get; set; }
    public string SimpleString { get; set; }
    public DateTime? SimpleDateTime { get; set; }
    private IList<Child> _children;
    public IEnumerable<Child> Children
    {
        get { return _children; }
    }
    public void AddChild(Child child)
    {
        child.Parent = this;
        _children.Add(child);
    }
}
public class Child
{
    public int Id { get; set; }
    public string SimpleString { get; set; }
    public DateTime? SimpleDateTime { get; set; }
    [JsonIgnore]
    public Parent Parent { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
我已经设置了Fluent NHibernate映射,如下所示:
public class ParentMap : ClassMap<Parent>
{
    public ParentMap()
    {
        Not.LazyLoad();
        Id(x => x.Id);
        Map(x => x.SimpleString);
        Map(x => x.SimpleDateTime);
        HasMany(x => x.Children)
            .Not.LazyLoad()
            .KeyColumn("ParentId").Cascade.AllDeleteOrphan()
            .Access.ReadOnlyPropertyThroughCamelCaseField(Prefix.Underscore);
    }
}
public class ChildMap : ClassMap<Child>
{
    public ChildMap()
    {
        Not.LazyLoad();
        Id(x => x.Id);
        Map(x => x.SimpleString);
        Map(x => x.SimpleDateTime);
        References(x => x.Parent).Not.Nullable().Column("ParentId").Cascade.All().Fetch.Join();
    }
}
Run Code Online (Sandbox Code Playgroud)
我告诉NHibernate,Cascade.AllDeleteOrphan()但它仍然试图将ParentId foriegn键设置为null,这是我设置的测试:
public void Delete_GivenTableWithChildren_WillBeDeletedFromDB()
{
    int id;
    using (var createSession = MsSqlSessionProvider.SessionFactory.OpenSession())
    {
        var parent = new Parent();
        parent.AddChild(new Child { SimpleString = "new child from UI" });
        using (var trx = createSession.BeginTransaction())
        {
            createSession.Save(parent);
            trx.Commit();
            id = parent.Id;
        }
    }
    using (var firstGetSession = MsSqlSessionProvider.SessionFactory.OpenSession())
    {
        var result = firstGetSession.Get<Parent>(id);
        Assert.IsNotNull(result);
    }
    using (var deleteSession = MsSqlSessionProvider.SessionFactory.OpenSession())
    {
        using (var trx = deleteSession.BeginTransaction())
        {
            deleteSession.Delete("from " + typeof(Parent).Name + " o where o.Id = :Id", id, NHibernateUtil.Int32);
            trx.Commit();
        }
    }
    using (var session = MsSqlSessionProvider.SessionFactory.OpenSession())
    {
        var result = session.Get<Parent>(id);
        Assert.IsNull(result);
    }
}
Run Code Online (Sandbox Code Playgroud)
deleteSession.Delete尝试以下SQL后,该行失败:
exec sp_executesql N'UPDATE [Child] SET ParentId = null WHERE ParentId = @p0',N'@p0 int',@p0=5
Run Code Online (Sandbox Code Playgroud)
有:
NHibernate.Exceptions.GenericADOException : could not delete collection: [SaveUpdateOrCopyTesting.Parent.Children#5][SQL: UPDATE [Child] SET ParentId = null WHERE ParentId = @p0]
  ----> System.Data.SqlClient.SqlException : Cannot insert the value NULL into column 'ParentId', table 'SaveUpdateCopyTestingDB.dbo.Child'; column does not allow nulls. UPDATE fails.
The statement has been terminated.
Run Code Online (Sandbox Code Playgroud)
有没有人知道我在映射中做错了什么,或者知道一种方法来阻止NHibernate试图使外键id无效?
谢谢
戴夫
nki*_*kes 19
尝试在ParentMap的HasMany上设置.Inverse(),如下所示:
HasMany(x => x.Children)
        .Not.LazyLoad()
        .KeyColumn("ParentId").Cascade.AllDeleteOrphan().Inverse()
        .Access.ReadOnlyPropertyThroughCamelCaseField(Prefix.Underscore);
Run Code Online (Sandbox Code Playgroud)
        |   归档时间:  |  
           
  |  
        
|   查看次数:  |  
           5226 次  |  
        
|   最近记录:  |