运行看似简单的查询时,我收到一个奇怪的错误。
return (from x in session.Query<Contact>()
.Where(x => x.Id == 10)
select new ContactIndexViewModel
{
Id = x.Id,
Name = x.BasicInfo.FirstName + " " + x.BasicInfo.LastName,
Filters = x.Filters
}).FirstOrDefault();
正在生成以下SQL
select
contact0_.[Id] as col_0_0_,
contact0_.[BasicInfoFirstName] as col_1_0_,
contact0_.[BasicInfoLastName] as col_2_0_,
. as col_3_0_,
filters1_.[Id] as column1_16_,
filters1_.Criteria1 as Criteria2_16_,
// .. .more filters1_ fields
filters1_.ContactId as ContactId16_
from
[MyServer].[dbo].[Contact] contact0_
inner join [MyServer].[dbo].[Filter] filters1_
on contact0_.[Id]=filters1_.ContactId
where
contact0_.[Id]=@p0
请注意选择的第四列。 BasicInfo是一个组件,select(在查询中)包括ViewModel中定义的所有字段。
我没有在应用程序的其他部分中使用Contact或Filter对象的任何其他问题。联系 - &gt;过滤器具有一对多的关系。
有关如何调试或可能导致此问题的任何想法?
更新
如果删除select
中对过滤器的引用,则问题就会消失。
更新相关映射
联系
public partial class ContactMap : ClassMap<Contact>
{
/// <summary>Initializes a new instance of the <see cref="ContactMap"/> class.</summary>
public ContactMap()
{
Table("[MyServer].[dbo].[Contact]");
OptimisticLock.Version();
DynamicUpdate();
LazyLoad();
Id(x=>x.Id)
.Access.CamelCaseField(Prefix.Underscore)
.Column("[Id]")
.GeneratedBy.Identity();
Version(x=>x.RecordVersion)
.Access.CamelCaseField(Prefix.Underscore)
.Column("[RecordVersion]")
.CustomSqlType("timestamp")
.Not.Nullable()
.UnsavedValue("null")
.CustomType("BinaryBlob")
.Generated.Always();
Map(x=>x.Active).Access.CamelCaseField(Prefix.Underscore);
// other scalar properties
Component(x0=>x0.BasicInfo, m0=>
{
m0.Map(x1=>x1.FirstName).Column("[BasicInfoFirstName]").Access.CamelCaseField(Prefix.Underscore);
m0.Map(x1=>x1.LastName).Column("[BasicInfoLastName]").Access.CamelCaseField(Prefix.Underscore);
// other scalar properties
});
// other relationships
HasMany(x=>x.Searches)
.Access.CamelCaseField(Prefix.Underscore)
.Cascade.AllDeleteOrphan()
.Fetch.Select()
.Inverse()
.LazyLoad()
.KeyColumns.Add("ContactId");
}
}
搜索
public partial class SearchMap : ClassMap<Search>
{
public SearchMap()
{
Table("[MyServer].[dbo].[Search]");
OptimisticLock.Version();
DynamicUpdate();
LazyLoad();
Id(x=>x.Id)
.Access.CamelCaseField(Prefix.Underscore)
.Column("[Id]")
.GeneratedBy.Identity();
Map(x=>x.Controller).Not.Nullable().Access.CamelCaseField(Prefix.Underscore);
Map(x=>x.Module).Not.Nullable().Access.CamelCaseField(Prefix.Underscore);
Map(x=>x.Name).Column("[Name]").Not.Nullable().Access.CamelCaseField(Prefix.Underscore);
References(x=>x.Contact)
.Access.CamelCaseField(Prefix.Underscore)
.Cascade.All()
.Fetch.Select()
.Columns("ContactId");
HasMany(x=>x.DataFilters)
.Access.CamelCaseField(Prefix.Underscore)
.Cascade.AllDeleteOrphan()
.Fetch.Select()
.Inverse()
.LazyLoad()
.KeyColumns.Add("SearchId");
}
}
答案 0 :(得分:0)
您是否使用FetchMode.Join映射过滤器?
顺便说一句,在内存中创建ContactIndexViewModel
可能更容易,因为它会从数据库中获取太多列。另一方面,Get
不会刷新会话,这可能与性能相关。
var contact = session.Get<Contact>(10);
return new ContactIndexViewModel
{
Id = contact.Id,
Name = contact.BasicInfo.FirstName + " " + contact.BasicInfo.LastName,
Filters = contact.Filters
};
答案 1 :(得分:0)
您对该表的映射对我来说并不常见。
Table("[MyServer].[dbo].[Contact]");
通常在配置期间提供服务器名称,模式单独说明,分隔符(“[...]”)由NHibernate设置。我会将其映射为:
Schema("dbo");
Table("Contact");
这可能导致解析问题导致奇数选择。如果不是这样,那么我认为这是一个错误 - NHibernate不应该在没有表别名和列名的情况下发出select。