我有以下数据模型:人可以有一个CurrentSpouse,这个当前的配偶可以有一辆车。数据模型仅用于演示。
人
public class BDOPerson
{
public virtual long? OID { get; set; }
public virtual string FirstName { get; set; }
public virtual string SureName { get; set; }
public virtual BDOCurrentSpouse CurrentSpouse { get; set; }
}
public class PersonMap : ClassMap<BDOPerson>
{
public PersonMap()
{
Table("T0001_Person");
Id(x => x.OID).Column("T0001OID").GeneratedBy.Increment();
Map(x => x.FirstName).Not.Nullable().Column("T0001Firstname");
Map(x => x.SureName).Not.Nullable().Column("T0001Surename");
References(x => x.CurrentSpouse).Nullable().Column("T0002_CurrentSpouseOID").Unique(); //HasOne opossite
}
}
CurrentSpouse
public class BDOCurrentSpouse
{
public virtual long? OID { get; set; }
public virtual string FirstName { get; set; }
public virtual string SureName { get; set; }
public virtual BDOPerson Person { get; set; }
public virtual BDOCar Car { get; set; }
}
public class CurrentSpouseMap : ClassMap<BDOCurrentSpouse>
{
public CurrentSpouseMap()
{
Table("T0002_CurrentSpouse");
Id(x => x.OID).Column("T0002OID").GeneratedBy.Increment();
Map(x => x.FirstName).Not.Nullable().Column("T0002Firstname");
Map(x => x.SureName).Not.Nullable().Column("T0002Surename");
HasOne(x => x.Person).PropertyRef(x => x.CurrentSpouse);
References(x => x.Car).Nullable().Column("T0003_CarOID");
}
}
汽车
public class BDOCar
{
public virtual long? OID { get; set; }
public virtual string PlateId { get; set; }
}
public class CarMap : ClassMap<BDOCar>
{
public CarMap()
{
Table("T0003_Car");
Id(x => x.OID).Column("T0003OID").GeneratedBy.Increment();
Map(x => x.PlateId).Not.Nullable().Column("T0003PlateId");
}
}
数据填充:
using (var session = _sessionFactory.OpenSession())
{
var isolationLevel = IsolationLevel.ReadCommitted;
using (var transaction = session.BeginTransaction(isolationLevel))
{
var currentSpouse = new BDOCurrentSpouse { FirstName = "Ema", SureName = "NiceLooking" };
var person = new BDOPerson { FirstName = "John", SureName = "Doe", CurrentSpouse = currentSpouse};
var car = new BDOCar { PlateId = "1234567" };
session.Save(car);
car = new BDOCar { PlateId = "336699" };
session.Save(car);
currentSpouse.Car = car;
session.Save(currentSpouse);
session.Save(person);
transaction.Commit();
}
}
选择数据 - 问题1
using (var session = _sessionFactory.OpenSession())
{
var isolationLevel = IsolationLevel.ReadCommitted;
using (var transaction = session.BeginTransaction(isolationLevel))
{
var v = session.Query<BDOPerson>().Fetch(x => x.CurrentSpouse).ToList();
transaction.Commit();
}
}
选择
的结果查询select bdoperson0_.T0001OID as t1_2_0_, bdocurrent1_.T0002OID as t1_1_1_, bdoperson0_.T0001Firstname as t2_2_0_, bdoperson0_.T0001Surename as t3_2_0_, bdoperson0_.T0002_CurrentSpouseOID as t4_2_0_, bdocurrent1_.T0002Firstname as t2_1_1_, bdocurrent1_.T0002Surename as t3_1_1_, bdocurrent1_.T0003_CarOID as t4_1_1_ from T0001_Person bdoperson0_ left outer join T0002_CurrentSpouse bdocurrent1_ on bdoperson0_.T0002_CurrentSpouseOID=bdocurrent1_.T0002OID
SELECT bdoperson0_.T0001OID as t1_2_0_, bdoperson0_.T0001Firstname as t2_2_0_, bdoperson0_.T0001Surename as t3_2_0_, bdoperson0_.T0002_CurrentSpouseOID as t4_2_0_ FROM T0001_Person bdoperson0_ WHERE bdoperson0_.T0002_CurrentSpouseOID=?
获得第二次选择的原因是什么?第二个选择创建N + 1问题 - 作为第一个选择的结果,对于DB中的每一行,完成特殊的第二个选择。
出于测试目的,我试图获取人
using (var session = _sessionFactory.OpenSession())
{
var isolationLevel = IsolationLevel.ReadCommitted;
using (var transaction = session.BeginTransaction(isolationLevel))
{
var v = session.Query<BDOPerson>().Fetch(x => x.CurrentSpouse).ThenFetch(x => x.Person).ToList();
transaction.Commit();
}
}
但这并未解决问题:
select bdoperson0_.T0001OID as t1_2_0_, bdocurrent1_.T0002OID as t1_1_1_, bdoperson2_.T0001OID as t1_2_2_, bdoperson0_.T0001Firstname as t2_2_0_, bdoperson0_.T0001Surename as t3_2_0_, bdoperson0_.T0002_CurrentSpouseOID as t4_2_0_, bdocurrent1_.T0002Firstname as t2_1_1_, bdocurrent1_.T0002Surename as t3_1_1_, bdocurrent1_.T0003_CarOID as t4_1_1_, bdoperson2_.T0001Firstname as t2_2_2_, bdoperson2_.T0001Surename as t3_2_2_, bdoperson2_.T0002_CurrentSpouseOID as t4_2_2_ from T0001_Person bdoperson0_ left outer join T0002_CurrentSpouse bdocurrent1_ on bdoperson0_.T0002_CurrentSpouseOID=bdocurrent1_.T0002OID left outer join T0001_Person bdoperson2_ on bdocurrent1_.T0002OID=bdoperson2_.T0002_CurrentSpouseOID
SELECT bdoperson0_.T0001OID as t1_2_0_, bdoperson0_.T0001Firstname as t2_2_0_, bdoperson0_.T0001Surename as t3_2_0_, bdoperson0_.T0002_CurrentSpouseOID as t4_2_0_ FROM T0001_Person bdoperson0_ WHERE bdoperson0_.T0002_CurrentSpouseOID=?
如何防止在映射中设置为HasOne的对象的额外选择?