Nhibernate 具有两个自然键的多对多关系
我有以下映射 UserProfile.hbm.xmlNhibernate 具有两个自然键的多对多关系,nhibernate,Nhibernate,我有以下映射 UserProfile.hbm.xml <?xml version="1.0" encoding="utf-8" ?> <hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="AngusBook.Domain" namespace="AngusBook.Domain"> <class name="Us
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
assembly="AngusBook.Domain"
namespace="AngusBook.Domain">
<class name="UserProfile">
<id name="UserId" type="int">
<generator class="identity" />
</id>
<natural-id mutable="false">
<property name="UserName" />
</natural-id>
<set name="Companies" table="Users_Companies">
<key column="UserId"/>
<many-to-many column="CompanyId" class="Company" />
</set>
</class>
</hibernate-mapping>
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="AngusBook.Domain" namespace="AngusBook.Domain" >
<class name="Company">
<id name="Id">
<generator class="hilo" />
</id>
<natural-id mutable="false">
<property name="CompanyName" />
</natural-id>
<set name="Users" table="Users_Companies">
<key column="CompanyId"/>
<many-to-many column="UserId" class="UserProfile" />
</set>
</class>
</hibernate-mapping>
Company.hbm.xml
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
assembly="AngusBook.Domain"
namespace="AngusBook.Domain">
<class name="UserProfile">
<id name="UserId" type="int">
<generator class="identity" />
</id>
<natural-id mutable="false">
<property name="UserName" />
</natural-id>
<set name="Companies" table="Users_Companies">
<key column="UserId"/>
<many-to-many column="CompanyId" class="Company" />
</set>
</class>
</hibernate-mapping>
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="AngusBook.Domain" namespace="AngusBook.Domain" >
<class name="Company">
<id name="Id">
<generator class="hilo" />
</id>
<natural-id mutable="false">
<property name="CompanyName" />
</natural-id>
<set name="Users" table="Users_Companies">
<key column="CompanyId"/>
<many-to-many column="UserId" class="UserProfile" />
</set>
</class>
</hibernate-mapping>
表格设计
通过这种映射,我可以在Users\u companys表中拥有两个相同的行(即:两行具有属于UserProfile和Company表的相同外键对)使用映射,当试图将一对外键插入表中已存在的用户公司时,如何使NHibernate或SQL抛出错误/异常?我希望用户公司中的每一行都是唯一的,并且没有重复数据。我发现了问题。我没有正确实现Equals()和GetHashCode() 我最终重构了我的实体,以使用以下基本实体类,从而解决了这个问题。将重复实体添加到集合时不会引发错误,但集合不会添加重复实体 实体.cs 公共抽象类实体 {
public virtual TId Id { get; protected set; }
protected virtual int Version { get; set; }
public override bool Equals(object obj)
{
return Equals(obj as Entity<TId>);
}
private static bool IsTransient(Entity<TId> obj)
{
return obj != null &&
Equals(obj.Id, default(TId));
}
private Type GetUnproxiedType()
{
return GetType();
}
public virtual bool Equals(Entity<TId> other)
{
if (other == null)
return false;
if (ReferenceEquals(this, other))
return true;
if (!IsTransient(this) &&
!IsTransient(other) &&
Equals(Id, other.Id))
{
var otherType = other.GetUnproxiedType();
var thisType = GetUnproxiedType();
return thisType.IsAssignableFrom(otherType) ||
otherType.IsAssignableFrom(thisType);
}
return false;
}
public override int GetHashCode()
{
if (Equals(Id, default(TId)))
return base.GetHashCode();
return Id.GetHashCode();
}
}
public abstract class Entity : Entity<Guid>
{
}
public virtual TId Id{get;protected set;}
受保护的虚拟int版本{get;set;}
公共覆盖布尔等于(对象对象对象)
{
收益等于(obj作为实体);
}
私有静态布尔值是瞬态的(实体obj)
{
返回对象!=null&&
等于(对象Id,默认值(TId));
}
私有类型GetUnproxiedType()
{
返回GetType();
}
公共虚拟布尔等于(实体其他)
{
如果(其他==null)
返回false;
if(ReferenceEquals(this,other))
返回true;
如果(!IsTransient)(此)&&
!IsTransient(其他)&&
等于(Id,其他.Id))
{
var otherType=other.GetUnproxiedType();
var thisType=GetUnproxiedType();
返回此类型。IsAssignableFrom(其他类型)||
otherType.IsAssignableFrom(此类型);
}
返回false;
}
公共覆盖int GetHashCode()
{
如果(等于(Id,默认值(TId)))
返回base.GetHashCode();
返回Id.GetHashCode();
}
}
公共抽象类实体:实体
{
}
UserProfile.cs
public class UserProfile : Entity<int>
{
public UserProfile()
{
Companies = new HashedSet<Company>();
}
public virtual string UserName { set; get; }
public virtual ISet<Company> Companies { set; get; }
}
public class Company : Entity<int>
{
public Company()
{
Users = new HashedSet<UserProfile>();
}
public Company(string name) :this()
{
this.CompanyName = name;
}
public virtual string CompanyName { set; get; }
public virtual ISet<UserProfile> Users { set; get; }
}
公共类用户配置文件:实体
{
公共用户配置文件()
{
companys=新HashedSet();
}
公共虚拟字符串用户名{set;get;}
公共虚拟ISet公司{set;get;}
}
Company.cs
public class UserProfile : Entity<int>
{
public UserProfile()
{
Companies = new HashedSet<Company>();
}
public virtual string UserName { set; get; }
public virtual ISet<Company> Companies { set; get; }
}
public class Company : Entity<int>
{
public Company()
{
Users = new HashedSet<UserProfile>();
}
public Company(string name) :this()
{
this.CompanyName = name;
}
public virtual string CompanyName { set; get; }
public virtual ISet<UserProfile> Users { set; get; }
}
公共类公司:实体
{
上市公司()
{
Users=新的HashedSet();
}
上市公司(字符串名称):this()
{
this.CompanyName=名称;
}
公共虚拟字符串CompanyName{set;get;}
公共虚拟ISet用户{set;get;}
}