【发布时间】:2011-09-15 19:43:37
【问题描述】:
我正在使用 NHibernate 3.x 以及 Fluent NHibernate,并且到目前为止构建数据库查询没有任何问题。
为了在本文中简化我的对象,我在下面包含了我的对象和映射结构的子集:
IssueItem POCO 实体类:
public class IssueItem : DomainEntity, IKeyed<Guid> {
public virtual Guid ID { get; set; }
public virtual string Subject { get; set; }
public virtual string Description { get; set; }
public virtual IList<IssueLocation> Locations { get; set; }
}
Location POCO 实体类:
public class Location : DomainEntity, IKeyed<Guid> {
public virtual Guid ID { get; set; }
public virtual string City { get; set; }
public virtual string State { get; set; }
public virtual string Zip { get; set; }
public virtual string Organization { get; set; }
public virtual IssueItem Issue { get; set; }
}
IssueItem流畅的NHibernate地图:
public class IssueItemMap : DomainEntityMapping<IssueItem> {
public IssueItemMap()
{
Table("IssueItem");
LazyLoad();
Map(x => x.ID).Column("ID");
Map(x => x.Subject).Column("Subject");
Map(x => x.Description).Column("Description");
HasMany(x => x.Locations).KeyColumn("IssueItemID").LazyLoad().ReadOnly().Inverse();
}
}
Location流畅的NHibernate地图:
public class LocationMap : DomainEntityMapping<Location> {
public LocationMap()
{
Table("Location");
LazyLoad();
Map(x => x.ID).Column("ID");
Map(x => x.City).Column("City");
Map(x => x.State).Column("State");
Map(x => x.Zip).Column("Zip");
Map(x => x.Organization).Column("Organization");
References(x => x.IssueItem).ForeignKey("IssueItemID").LazyLoad().ReadOnly();
}
}
现在,我在我的 MVC 应用程序中使用了工作单元和服务/存储库模式。因此,我的项目有一个域层,其中包含我的基本 POCO 实体,以及验证器和服务。在我的数据层中,我有我的 NHibernate 相关的东西,例如我的存储库,我的域层从我的服务访问。这也是我的 NHibernate 地图所在的位置。
为了确保没有特定于 NHibernate 的逻辑渗入我的域层(以防我将来想使用不同的 ORM),我在域层的服务中针对从返回的 IQueryable 对象执行 LINQ 语句我的数据层中的存储库。因此,当我编写查询时,我使用 System.Linq 和 System.Linq.Expressions 而不是 NHibernate.Linq 类。
也就是说,这是我在域层中的一个服务类中遇到问题的 LINQ 查询:
var issues = _issueRepo.All();
if (!string.IsNullOrWhiteSpace(searchWords)) {
issues = issues.Where(i => i.Subject.Contains(searchWords)
|| i.Description.Contains(searchWords)
|| i.Locations.Where(l => l.Organization.Contains(searchWords)
|| l.City.Contains(searchWords))
.Select(x => x.IssueItemID).Contains(i.ID)
);
}
现在,IssueItems 可以正常查询了。但是,未正确查询一对多表(Locations)。这就是我的意思...
生成的 T-SQL 语句是完美的,除了它的最后。示例:
select TOP(100) issueitem0_.ID as ID2_, issueitem0_.Subject as Subject2_, issueitem0_.Description as Description2_
from IssueItem issueitem0_
where issueitem0_.Subject like ('%test%') or issueitem0_.Description like ('%test%')
or exists (select location1_.IssueItemID from Location location1_ where
issueitem0_.ID=location1_.IssueItemID and (location1_.Organization like ('%test%')
or location1_.City like ('%test%')) and location1_.ID=issueitem0_.ID)
看到最后一点了吗?它抛出了最后一个“和”语句(和 location1_.ID=issueitem0_.ID),这在整个系统中抛出了一个扳手。我已经调整了我的映射可以想到的每个配置参数,并尝试了许多不同的 LINQ 语句,但我无法摆脱最后一部分。我不知道为什么它会添加它。
如果我在 LINQPad 中构造相同的 LINQ 语句,它会正确生成没有最后一部分(和 location1_.ID=issueitem0_.ID)的 T-SQL 语句。
有什么想法吗?
谢谢! 乔尔
【问题讨论】:
标签: linq nhibernate c#-4.0 fluent-nhibernate