[英]LINQ join query with relational entities
我使用的是ef-core 2.1,我有以下簡化實體,其中一個Account
映射到零個或多個Attribute
對象:
public class Account
{
public int Id { get; set; }
public int LongId { get; set; }
public List<Attribute> Attributes { get; set; }
}
public class Attribute
{
public int Id { get; set; }
public string Name { get; set; }
public string Value { get; set; }
public Account Account { get; set; }
}
我有類似的字符串的初始集合Attribute.Value
對於給定的固定Attribute.Name
,我想找到第二個相關的Attribute
從相同的父對象Account
,並獲得其Attribute.Value
。
我想在最初的字符串集合中加入ef實體,這樣我就可以很容易地推斷:
Account
或沒有相關Attribute
對象的Account
(兩者都等同於相同的用例)。 Account
並且它包含所有必需的Attribute
對象,我想獲取輔助Attribute
的值。 沒有LINQ和ef,我運行以下SQL查詢,忽略父Account
並生成我想要的結果集:
CREATE TABLE #Temp
(
id nvarchar(20) not null
);
INSERT INTO #Temp (id) VALUES ('cejawq'), ('issokq'), ('cqlpjq'), ('mbgzvi'), ('wqwlff'), ('iedifh');
SELECT t.[Id], attr2.[Value]
FROM #Temp t
LEFT OUTER JOIN [dbo].[Attributes] attr1
ON t.[Id]=attr1.[Value]
AND attr1.[Name]='uid'
LEFT OUTER JOIN [dbo].[Attributes] attr2
ON attr1.[AccountId]=attr2.[AccountId]
AND attr2.[Name]='objType';
我得到以下結果集:
id|objType
-----------
cejawq|ext
issokq|ext
cqlpjq|int
mbgzvi|int
wqwlff|ext
iedifh|null
我正在努力將其映射到高效的LINQ,以便生成的SQL遠程生成結果集並將我可以投影的數據發送回等效的匿名類型。 我是否需要關心LINQ案例中的父對象? 我在Attribute.Value
列上沒有索引。
Attributes
表包含以下數據:
Id|Name |Value |AccountId
1 |uid |cejawq|1
2 |objType|ext |1
3 |uid |issokq|2
4 |objType|ext |2
5 |uid |cqlpjq|3
6 |objType|int |3
7 |uid |mbgzvi|4
8 |objType|int |4
9 |uid |wqwlff|5
10|objType|ext |5
由於EF Core不支持與內存序列(但尚未)的連接,您可以將查詢拆分為兩部分 - 一部分采用數據服務器端( [Attributes
到[Attributes
連接],使用內存集合作為過濾器(SQL IN
through LINQ Contains
方法),第二個使用db查詢的結果在內存中執行左連接:
DbContext db = ...;
var uids = new [] { "cejawq", "issokq", "cqlpjq", "mbgzvi", "wqwlff", "iedifh" };
var dbQuery =
from attr1 in db.Set<Attribute>()
where attr1.Name == "uid" && uids.Contains(attr1.Value)
join attr2 in db.Set<Attribute>()
on new { AccountId = attr1.Account.Id, Name = "objType" }
equals new { AccountId = attr2.Account.Id, attr2.Name }
into attr2Group from attr2 in attr2Group.DefaultIfEmpty() // left outer join
select new { uid = attr1.Value, objType = attr2.Value };
var query =
from uid in uids
join dbResult in dbQuery on uid equals dbResult.uid
into dbResultGroup from dbResult in dbResultGroup.DefaultIfEmpty() // left outer join
select new { uid, dbResult?.objType };
var result = query.ToList();
它轉換為單個數據庫查詢,如下所示:
SELECT [attr1].[Value] AS [uid], [attr2].[Value] AS [objType]
FROM [Attributes] AS [attr1]
LEFT JOIN [Attributes] AS [attr2] ON ([attr1].[AccountId] = [attr2].[AccountId]) AND (N'objType' = [attr2].[Name])
WHERE ([attr1].[Name] = N'uid') AND [attr1].[Value] IN (N'cejawq', N'issokq', N'cqlpjq', N'mbgzvi', N'wqwlff', N'iedifh')
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.