假设以下类:
public class A
{
public virtual ind Id { get; set; }
public virtual int Number { get; protected set; }
}
public class B : A
{
public virtual string SomeValue { get; set; }
public virtual int BookingNumber
{
get { return Number; }
set { Number = value; }
}
}
public class C : A
{
public virtual string SomeOtherValue { get; set; }
public virtual int AccountNumber
{
get { return Number; }
set { Number = value; }
}
}
正如您所看到的,我想以不同的名称公开属性Number。
现在我想绘制A、B、C的地图。
public class AMap : ClassMap<A>
{
public AMap()
{
Id(x => x.Id);
Map(x => x.Number);
}
}
public class BMap : SubclassMap<B>
{
public BMap()
{
Map(x => x.SomeValue);
}
}
public class CMap : SubclassMap<C>
{
public CMap()
{
Map(x => x.SomeOtherValue);
}
}
有了这个映射,我可以将内容保存到数据库中。
但是,当我查询B或C时:
Session.QueryOver<B>().Where(x => x.BookingNumber).List();
我收到错误could not resolve property: BookingNumber of: B
我做错了什么?
怎么了?在未映射的属性上生成查询。
(用不同的名称包装派生类中的基属性至少很奇怪),如果真的需要这种方法,因为一些上层需要不同的相同属性的名称。。。那么,好吧,好吧。但是,NHibernate一定是提供了不同的信息集。
将您的查询视为自描述性信息,其中包含的信息足以转换为SQL语句。
因此,如果您使用QueryOver<B>.Where(x => x.BookingNumber == 1)...
。信息是(解析lambda表达式时):
- 使用C#对象CCD_ 3
- 找到其性质CCD_ 4
- 找到它的映射表示:列名CCD_ 5
- 取值:
1
- 生成查询
WHERE BookingNumberColumn = 1
在这种情况下,步骤3失败。没有列映射到BookingNumber
。。。
解决方案是,至少在数据(NHibernate)层上,应用基于基类A
映射的过滤器
Session
.QueryOver<B>()
.Where(x => x.Number == 1) // use the A.Number MAPPED property
.List<B>();
但是,根据我的经验,我们主要做的是转换持久性中的差异(不同的id列名,不同的代码列),并将它们映射到具有通用简化结构的C#基类或接口。
点击此处获取更多信息:16。QueryOver查询