Fluent Nhibernate:使用 compositeId 键引用实体
Fluent Nhibernate: key-referencing an entity with a compositeId
我在使用 Fluent Nhibernate 映射这些关系时遇到问题:
请求实体:
- 编号
- 日期
学校实体:
- 复合 ID 由
- 名字
- 请求
- 属性
位置实体:
- 复合 ID 由
- 存在(布尔值)
- 学校(-> school_name 和 request_id 上的外键)
- 省
基本上,这些关系代表了我向某个网络 api 服务询问学校的情况。我想保存请求(我在这里只放了日期,但我有更多的字段)和为学校检索的信息。我还想将此信息与生成信息的请求绑定。
我也想像以前一样保存学校位置和绑定这些信息
到目前为止我做了什么:
School.cs:
public class School
{
public virtual string name {get; set;}
public virtual Request request {get; set;}
public virtual string property;
}
Request.cs:
public class Request
{
public virtual int id {get; set;}
public virtual DateTime date {get; set;}
}
Location.cs:
public class Location
{
public virtual bool exist {get; set;}
public virtual School school {get; set;}
public virtual string province {get; set;}
}
SchoolMap.cs
public class SchoolMap : ClassMap<School>
{
public SchoolMap() {
CompositeId().KeyProperty(x => x.name, "name")
.KeyProperty(x => x.request, "request_id");
Map(x => x.property);
}
}
RequestMap.cs
public class Request : ClassMap<Request>
{
public SchoolMap() {
Id(x => x.id).GeneratedBy.Identity();
Map(x => x.date);
}
}
LocationMap.cs
public class LocationMap : ClassMap<Location>
{
public LocationMap() {
CompositeId().KeyProperty(x => x.exist)
.KeyReference(x => x.school, new string[] {"name", "request_id"});
References<School>(x => x.school).Columns(new string [] {"name", "request_id"}).Cascade.All();
Map(x => x.province);
}
}
我还实现了每个继承自 AbstractRepository 的存储库。
"save" 方法是(例如 SchoolRepository)
public School saveSchool(School school)
{
var transaction = openTransaction();
session.saveOrUpdate(school);
transaction.commit();
return school;
}
这个方案行不通。
如果我(按此顺序)创建并保存一个请求,然后一所学校引用该请求,然后一个位置引用该学校,我会收到一个 "SqlParameter OutOfBound" 异常。
我不知道如何映射这种关系。
在此先感谢大家。
我尝试演示一些复合 ID 关系。
public class EntityA
{
public EntityA()
{
Id = new EntityAId();
}
public virtual EntityAId Id { get; protected set; }
}
public class EntityAMap : FluentNHibernate.Mapping.ClassMap<EntityA>
{
public EntityAMap()
{
CompositeId(t => t.Id).KeyProperty(t => t.Id).CustomType<int>();
}
}
public class EntityB
{
private EntityA _EntityA;
public EntityB()
{
Id = new EntityBId();
}
public virtual EntityBId Id { get; protected set; }
public virtual int EntityA_Id { get { return Id.EntityA_Id; } protected set { Id.EntityA_Id = value; } }
public virtual EntityA EntityA { get { return _EntityA; } set { _EntityA = value; EntityA_Id = value == null ? 0 : value.Id.Id; } }
}
public class EntityBMap : FluentNHibernate.Mapping.ClassMap<EntityB>
{
public EntityBMap()
{
CompositeId(t => t.Id).KeyProperty(t => t.Id).CustomType<int>()
.KeyProperty(t => t.EntityA_Id).CustomType<int>();
Map(t => t.EntityA_Id).Not.Insert().Not.Update();
References(t => t.EntityA).Columns("EntityA_Id");
}
}
public class EntityAId
{
public virtual int Id { get; set; }
public override bool Equals(object obj)
{
if (obj == null)
return false;
var t = obj as EntityAId;
if (t == null)
return false;
if (Id == t.Id)
return true;
return false;
}
public override int GetHashCode()
{
return (Id).GetHashCode();
}
}
public class EntityBId
{
public virtual int EntityA_Id { get; set; }
public virtual int Id { get; set; }
public override bool Equals(object obj)
{
if (obj == null)
return false;
var t = obj as EntityBId;
if (t == null)
return false;
if (EntityA_Id == t.EntityA_Id && Id == t.Id)
return true;
return false;
}
public override int GetHashCode()
{
return (EntityA_Id + "|" + Id).GetHashCode();
}
}
public class EntityC
{
private EntityA _EntityA;
private EntityB _EntityB;
public EntityC()
{
Id = new EntityCId();
}
public virtual EntityCId Id { get; protected set; }
public virtual int EntityA_Id { get { return Id.EntityA_Id; } protected set { Id.EntityA_Id = value; } }
public virtual EntityA EntityA { get { return _EntityA; } set { _EntityA = value; EntityA_Id = value == null ? 0 : value.Id.Id; } }
public virtual int EntityB_Id { get { return Id.EntityB_Id; } protected set { Id.EntityB_Id = value; } }
public virtual EntityB EntityB { get { return _EntityB; } set { _EntityB = value; EntityB_Id = value == null ? 0 : value.Id.Id; } }
}
public class EntityCMap : FluentNHibernate.Mapping.ClassMap<EntityC>
{
public EntityCMap()
{
CompositeId(t => t.Id).KeyProperty(t => t.Id).CustomType<int>()
.KeyProperty(t => t.EntityA_Id).CustomType<int>()
.KeyProperty(t => t.EntityB_Id).CustomType<int>();
Map(t => t.EntityA_Id).Not.Insert().Not.Update();
References(t => t.EntityA).Columns("EntityA_Id");
Map(t => t.EntityB_Id).Not.Insert().Not.Update();
References(t => t.EntityB).Columns("EntityA_Id", "EntityB_Id");
}
}
public class EntityCId
{
public virtual int EntityA_Id { get; set; }
public virtual int EntityB_Id { get; set; }
public virtual int Id { get; set; }
public override bool Equals(object obj)
{
if (obj == null)
return false;
var t = obj as EntityCId;
if (t == null)
return false;
if (EntityA_Id == t.EntityA_Id && EntityB_Id == t.EntityB_Id && Id == t.Id)
return true;
return false;
}
public override int GetHashCode()
{
return (EntityA_Id + "|" + EntityB_Id + "|" + Id).GetHashCode();
}
}
我在使用 Fluent Nhibernate 映射这些关系时遇到问题:
请求实体:
- 编号
- 日期
学校实体:
- 复合 ID 由
- 名字
- 请求
- 属性
位置实体:
- 复合 ID 由
- 存在(布尔值)
- 学校(-> school_name 和 request_id 上的外键)
- 省
基本上,这些关系代表了我向某个网络 api 服务询问学校的情况。我想保存请求(我在这里只放了日期,但我有更多的字段)和为学校检索的信息。我还想将此信息与生成信息的请求绑定。 我也想像以前一样保存学校位置和绑定这些信息
到目前为止我做了什么:
School.cs:
public class School
{
public virtual string name {get; set;}
public virtual Request request {get; set;}
public virtual string property;
}
Request.cs:
public class Request
{
public virtual int id {get; set;}
public virtual DateTime date {get; set;}
}
Location.cs:
public class Location
{
public virtual bool exist {get; set;}
public virtual School school {get; set;}
public virtual string province {get; set;}
}
SchoolMap.cs
public class SchoolMap : ClassMap<School>
{
public SchoolMap() {
CompositeId().KeyProperty(x => x.name, "name")
.KeyProperty(x => x.request, "request_id");
Map(x => x.property);
}
}
RequestMap.cs
public class Request : ClassMap<Request>
{
public SchoolMap() {
Id(x => x.id).GeneratedBy.Identity();
Map(x => x.date);
}
}
LocationMap.cs
public class LocationMap : ClassMap<Location>
{
public LocationMap() {
CompositeId().KeyProperty(x => x.exist)
.KeyReference(x => x.school, new string[] {"name", "request_id"});
References<School>(x => x.school).Columns(new string [] {"name", "request_id"}).Cascade.All();
Map(x => x.province);
}
}
我还实现了每个继承自 AbstractRepository 的存储库。 "save" 方法是(例如 SchoolRepository)
public School saveSchool(School school)
{
var transaction = openTransaction();
session.saveOrUpdate(school);
transaction.commit();
return school;
}
这个方案行不通。 如果我(按此顺序)创建并保存一个请求,然后一所学校引用该请求,然后一个位置引用该学校,我会收到一个 "SqlParameter OutOfBound" 异常。
我不知道如何映射这种关系。
在此先感谢大家。
我尝试演示一些复合 ID 关系。
public class EntityA
{
public EntityA()
{
Id = new EntityAId();
}
public virtual EntityAId Id { get; protected set; }
}
public class EntityAMap : FluentNHibernate.Mapping.ClassMap<EntityA>
{
public EntityAMap()
{
CompositeId(t => t.Id).KeyProperty(t => t.Id).CustomType<int>();
}
}
public class EntityB
{
private EntityA _EntityA;
public EntityB()
{
Id = new EntityBId();
}
public virtual EntityBId Id { get; protected set; }
public virtual int EntityA_Id { get { return Id.EntityA_Id; } protected set { Id.EntityA_Id = value; } }
public virtual EntityA EntityA { get { return _EntityA; } set { _EntityA = value; EntityA_Id = value == null ? 0 : value.Id.Id; } }
}
public class EntityBMap : FluentNHibernate.Mapping.ClassMap<EntityB>
{
public EntityBMap()
{
CompositeId(t => t.Id).KeyProperty(t => t.Id).CustomType<int>()
.KeyProperty(t => t.EntityA_Id).CustomType<int>();
Map(t => t.EntityA_Id).Not.Insert().Not.Update();
References(t => t.EntityA).Columns("EntityA_Id");
}
}
public class EntityAId
{
public virtual int Id { get; set; }
public override bool Equals(object obj)
{
if (obj == null)
return false;
var t = obj as EntityAId;
if (t == null)
return false;
if (Id == t.Id)
return true;
return false;
}
public override int GetHashCode()
{
return (Id).GetHashCode();
}
}
public class EntityBId
{
public virtual int EntityA_Id { get; set; }
public virtual int Id { get; set; }
public override bool Equals(object obj)
{
if (obj == null)
return false;
var t = obj as EntityBId;
if (t == null)
return false;
if (EntityA_Id == t.EntityA_Id && Id == t.Id)
return true;
return false;
}
public override int GetHashCode()
{
return (EntityA_Id + "|" + Id).GetHashCode();
}
}
public class EntityC
{
private EntityA _EntityA;
private EntityB _EntityB;
public EntityC()
{
Id = new EntityCId();
}
public virtual EntityCId Id { get; protected set; }
public virtual int EntityA_Id { get { return Id.EntityA_Id; } protected set { Id.EntityA_Id = value; } }
public virtual EntityA EntityA { get { return _EntityA; } set { _EntityA = value; EntityA_Id = value == null ? 0 : value.Id.Id; } }
public virtual int EntityB_Id { get { return Id.EntityB_Id; } protected set { Id.EntityB_Id = value; } }
public virtual EntityB EntityB { get { return _EntityB; } set { _EntityB = value; EntityB_Id = value == null ? 0 : value.Id.Id; } }
}
public class EntityCMap : FluentNHibernate.Mapping.ClassMap<EntityC>
{
public EntityCMap()
{
CompositeId(t => t.Id).KeyProperty(t => t.Id).CustomType<int>()
.KeyProperty(t => t.EntityA_Id).CustomType<int>()
.KeyProperty(t => t.EntityB_Id).CustomType<int>();
Map(t => t.EntityA_Id).Not.Insert().Not.Update();
References(t => t.EntityA).Columns("EntityA_Id");
Map(t => t.EntityB_Id).Not.Insert().Not.Update();
References(t => t.EntityB).Columns("EntityA_Id", "EntityB_Id");
}
}
public class EntityCId
{
public virtual int EntityA_Id { get; set; }
public virtual int EntityB_Id { get; set; }
public virtual int Id { get; set; }
public override bool Equals(object obj)
{
if (obj == null)
return false;
var t = obj as EntityCId;
if (t == null)
return false;
if (EntityA_Id == t.EntityA_Id && EntityB_Id == t.EntityB_Id && Id == t.Id)
return true;
return false;
}
public override int GetHashCode()
{
return (EntityA_Id + "|" + EntityB_Id + "|" + Id).GetHashCode();
}
}