[英]How to create this query using Entity Framework and Linq
在使用LinqKit的LinqPad中,我正在执行以下操作:
var topPredicate = PredicateBuilder.True<LandRecord>();
topPredicate = topPredicate.And(a=>a.InstrumentType == "DEED");
topPredicate = topPredicate.And(a=>a.BookType == "OFFICIAL RECORD");
var subPredicate = PredicateBuilder.True<LandRecord>();
subPredicate = subPredicate.And(a=>a.Parties.Any(b=>b.LastName == "SMITH"));
subPredicate = subPredicate.And(a=>a.Parties.Any(b=>b.FirstName == "John"));
LandRecords.AsExpandable().Include(a=>a.Parties).Where(topPredicate).Where(subPredicate).ToList();
这是它正在创建的SQL:
SELECT
[Extent1].[LandRecordID] AS [LandRecordID],
[Extent1].[DocumentID] AS [DocumentID],
[Extent1].[InstrumentNo] AS [InstrumentNo],
[Extent1].[BookType] AS [BookType],
[Extent1].[BookNo] AS [BookNo],
[Extent1].[PageNo] AS [PageNo],
[Extent1].[DateFiled] AS [DateFiled],
[Extent1].[DateInstrument] AS [DateInstrument],
[Extent1].[InstrumentType] AS [InstrumentType],
[Extent1].[MortgageAmount] AS [MortgageAmount]
FROM [LAND].[LandRecord] AS [Extent1]
WHERE (N'DEED' = [Extent1].[InstrumentType]) AND (N'OFFICIAL RECORD' = [Extent1].[BookType]) AND ( EXISTS (SELECT
1 AS [C1]
FROM [LAND].[Party] AS [Extent2]
WHERE ([Extent1].[LandRecordID] = [Extent2].[LandRecordID]) AND (N'SMITH' = [Extent2].[LastName])
)) AND ( EXISTS (SELECT
1 AS [C1]
FROM [LAND].[Party] AS [Extent3]
WHERE ([Extent1].[LandRecordID] = [Extent3].[LandRecordID]) AND (N'John' = [Extent3].[FirstName])
))
我要创建的SQL将是以下代码,其中LastName和FirstName都将在同一存在语句中组合/联接。
在生产中,该子查询可能包含1个或多个条件,每个条件都是startwith,endswith,contains或完全匹配。 因此,我需要能够一次手动构建1个子查询。
SELECT
[Extent1].[LandRecordID] AS [LandRecordID],
[Extent1].[DocumentID] AS [DocumentID],
[Extent1].[InstrumentNo] AS [InstrumentNo],
[Extent1].[BookType] AS [BookType],
[Extent1].[BookNo] AS [BookNo],
[Extent1].[PageNo] AS [PageNo],
[Extent1].[DateFiled] AS [DateFiled],
[Extent1].[DateInstrument] AS [DateInstrument],
[Extent1].[InstrumentType] AS [InstrumentType],
[Extent1].[MortgageAmount] AS [MortgageAmount]
FROM [LAND].[LandRecord] AS [Extent1]
WHERE (N'DEED' = [Extent1].[InstrumentType]) AND (N'OFFICIAL RECORD' = [Extent1].[BookType]) AND ( EXISTS (SELECT
1 AS [C1]
FROM [LAND].[Party] AS [Extent2]
WHERE ([Extent1].[LandRecordID] = [Extent2].[LandRecordID]) AND (N'SMITH' = [Extent2].[LastName] AND (N'John' = [Extent2].[FirstName])
))
您可以单独构建子谓词,如果包含任何内容,则将其添加到顶部谓词中:
var topPredicate = PredicateBuilder.True<LandRecord>();
topPredicate = topPredicate.And(a=>a.InstrumentType == "DEED");
topPredicate = topPredicate.And(a=>a.BookType == "OFFICIAL RECORD");
var subPredicate = PredicateBuilder.True<Party>();
if (!string.IsNullOrWhiteSpace(firstName)
{
subPredicate = subPredicate.And(b => b.FirstName == firstName);
}
if (!string.IsNullOrWhiteSpace(lastName)
{
subPredicate = subPredicate.And(b => b.LastName == lastName);
}
// If the subPredicate's body is still just PredicateBuilder.True<Party>(), ignore it.
if (!(subPredicate.Body is ConstantExpression))
{
topPredicate = topPredicate.And(lr => lr.Parties.AsQueryable().Any(subPredicate));
}
在这里, lr.Parties.AsQueryable()
的使用,因为Parties
可能是一个ICollection
,即IEnumerable
。 由于IEnumerable.Any
接受Func
而不是Expression
,因此如果没有AsQueryable()
,代码将无法编译。
顺便说一下,我的代码不包含AsExpandable()
因为我使用Universal PredicateBuilder 。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.