NHibernate与sqlite抛出GenericADOException“约束失败\ r \ n \ nFOREIGN KEY约束失败”试图保存

时间:2014-09-02 22:47:29

标签: c# sqlite unit-testing nhibernate fluent-nhibernate

我正在尝试为每个Ayende's recommendation设置一个内存中的sqlite数据库进行单元测试。一切都工作得很好,除了一个实体,UserPermission,总是导致NHibernate抛出GenericADOException“约束失败\ r \ nFOREIGN KEY约束失败”

这是标准的一对多关系;每个用户可以拥有零个,一个或多个UserPermissions。

以下是我的模特:

public class User
{
    public virtual int Id { get; set; }
    public virtual string LastName { get; set; }
    public virtual string FirstName { get; set; }
    public virtual IList<UserPermission> UserPermissions { get; set; }
}

public class UserPermission
{
    public virtual int Id { get; set; }
    public virtual int PermissionId { get; set; }
    public virtual User User { get; set; }
    public virtual Organization Organization { get; set; }
}

以下是映射:

public class UserMap : ClassMap<User>
{
    public UserMap()
    {
        Table("USERS");
        Id(x => x.Id).Column("USER_ID").GeneratedBy.Native(x => x.AddParam("sequence", "SEQ_USERS"));
        HasMany(x => x.UserPermissions);
        Map(x => x.LastName);
        Map(x => x.FirstName);
    }
}

public class UserPermissionMap : ClassMap<UserPermission>{
    public UserPermissionMap()
    {
        Table("USER_PERMISSION");
        Id(x => x.Id).Column("USER_PERMISSION_ID").GeneratedBy.Native(x => x.AddParam("sequence", "SEQ_USER_PERMISSION")); 
        Map(x => x.PermissionId);
        References(x => x.User).Column("USER_ID");
        References(x => x.Organization).Column("ORG_ID").Nullable();
    }
}

今天下午我搜索了很多,并且发现了几个看似相关的帖子,但他们的建议都没有对我有用。具体来说,这就是我的尝试:

  • 在UserMap中我尝试将Inverse()添加到HasMany(x =&gt; x.UserPermissions)
  • 同样在UserMap中我尝试将Cascade.All()添加到HasMany(x =&gt; x.UserPermissions)
  • 在UserPermissionMap中,我尝试将Cascade.All()添加到引用(x =&gt; x.User)
  • 以上
  • 的各种组合
  • 在我的测试中,组织总是为空但我已经尝试将其设置为虚拟组织并且没有修复它

疯狂的是我能够针对Oracle数据库创建和保存UserPermission对象;只有在我尝试针对sqlite保存UserPermission时才会发生此错误。

2 个答案:

答案 0 :(得分:0)

您可以尝试将HasMany映射定义为:

HasMany(x => x.UserPermissions)
  .KeyColumn("User_ID")
  .Cascade
  .AllDeleteOrphan()
  .Inverse();

AllDeleteOrphan会删除UserPermission作为从UserPermissions列表中删除的一部分。 如果它不是所需的行为,您可以用简单的.All替换它。

答案 1 :(得分:0)

弄清楚了。我们有一个Permission模型,其HasMany映射到UserPermission,但UserPermission没有对Permission模型的引用。有一次,UserPermission模型可能有一个Permission属性,它将返回Permission对象,然后我们将其更改为int并忘记更新Permission映射。

以下是我在PermissionMap中找到的内容:

public class PermissionMap : ClassMap<Permission>
{
    public PermissionMap()
    {
        Table("PERMISSION");
        Id(x => x.Id).Column("PERMISSION_ID");
        Map(x => x.Name);
        HasMany(x => x.UserPermissions).LazyLoad();  // Removed this line to fix issue
    }
}

经验教训:当您删除模型之间的关系时,请不要忘记将其从两侧移除。