问题描述
尝试与没有主键的表支持的实体建立HasMany
关系时遇到了最大的麻烦.
I am having the worst trouble trying to setup a HasMany
relationship to an entity backed by a table with no primary key.
ClassA
具有CompositeId
.为了避免在ClassB
上缺少primary key
,我尝试在ClassB
上创建一个CompositeId
,该表包含表中的所有列.无论我尝试了什么,都没有任何效果.
ClassA
has a CompositeId
. To circumvent the lack of a primary key
on ClassB
, I tried to create a CompositeId
on ClassB
that was comprised all of the columns in the table. No matter what I've tried, nothing has worked.
这些是我的类和映射.
These are my classes and mappings.
public class ClassA
{
public virtual int a_1_id {get;set;}
public virtual string a_2_id {get;set;}
public virtual IList<classB> ClassBs { get; set; }
public override int GetHashCode()
{
int hashCode = 0;
hashCode = hashCode ^ a_1_id ^ a_2_id.GetHashCode();
return hashCode;
}
public override bool Equals(object obj)
{
var toCompare = obj as ClassB;
return (toCompare != null) && (this.GetHashCode() != toCompare.GetHashCode());
}
}
public class ClassAMap : ClassMap<ClassA>
{
public ClassAMap()
{
Schema("dbo");
Table("ClassA");
Not.LazyLoad();
CompositeId()
.KeyProperty(x => x.a_1_id, "a_1_id")
.KeyProperty(x => x.a_2_id, "a_2_id");
HasMany(x => x.ClassBs)
.Table("ClassB")
.KeyColumn("a_2_id")
.Not.LazyLoad();
}
}
public class ClassB
{
public virtual string a_2_id {get;set;}
public virtual string b_field1 {get;set;}
public override int GetHashCode()
{
int hashCode = 0;
hashCode = hashCode
^ a_2_id.GetHashCode()
^ b_field1.GetHashCode();
return hashCode;
}
public override bool Equals(object obj)
{
var toCompare = obj as ClassB;
return (toCompare != null) && (this.GetHashCode() != toCompare.GetHashCode());
}
}
public class ClassBMap : ClassMap<ClassB>
{
public ClassBMap()
{
Schema("dbo");
Table("ClassB");
Not.LazyLoad();
CompositeId()
.KeyProperty(x => x.a_2_id, "a_2_id")
.KeyProperty(x => x.b_field1, "b_field1");
}
}
推荐答案
如果classB依赖于ClassA,则无需将classB映射为实体.
you do not need to map classB as entity if it is dependet on ClassA.
public class ClassA
{
public virtual int Id1 {get;set;}
public virtual string Id2 {get;set;}
public virtual IList<string> Bs { get; private set; }
public override int GetHashCode()
{
return (Id1 << 16) ^ Id2.GetHashCode();
}
public override bool Equals(object obj)
{
var toCompare = obj as ClassA;
return (toCompare != null) && (this.Id1 == toCompare.Id1) && (this.Id2 == toCompare.Id2);
}
}
public class ClassAMap : ClassMap<ClassA>
{
public ClassAMap()
{
Schema("dbo");
Table("ClassA");
Not.LazyLoad();
CompositeId()
.KeyProperty(x => x.Id1, "a_1_id")
.KeyProperty(x => x.Id2, "a_2_id");
HasMany(x => x.ClassBs)
.AsSet()
.Table("ClassB")
.KeyColumn("a_2_id")
.Not.LazyLoad(),
.Element("b_field1"); // if there is only 1 value column or
.Component(c => // if there is more than 1 value column
{
c.ParentReference(x => x.A);
c.Map(x => x.Value1, "b_field1");
c.Map(x => x.Value2, "b_field2");
c.Map(x => x.Value3, "b_field3");
});
}
}
public class ClassB
{
public virtual ClassA A {get;set;}
public virtual string Value1 {get;set;}
public virtual string Value2 {get;set;}
public virtual string Value3 {get;set;}
}
注意:ClassA的gethashcode实现是完全错误的,Euqals不应依赖哈希码,因为它将发生冲突
Note: the gethashcode implementation of ClassA is plain wrong and Euqals should not rely on hashcode because it will have collisions
这篇关于流利的nHibernate将HasMany映射到没有主键的实体/表的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!