gpt4 book ai didi

c# - LINQ 与关系实体的连接查询

转载 作者:行者123 更新时间:2023-11-30 12:20:21 25 4
gpt4 key购买 nike

我正在使用 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.Name,我有一个类似于 Attribute.Value 的初始字符串集合,我想找到第二个关联的 Attribute 来自同一父级 Account 的对象并获取其 Attribute.Value

我想根据初始字符串集合左连接 ef 实体,以便我可以轻松推断:

  1. 是否不存在相应的Account 或存在没有相关Attribute 对象的Account(两者等同于相同的用例)。<
  2. 如果 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 join) 在内存集合中用作过滤器(SQL IN 通过 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')

关于c# - LINQ 与关系实体的连接查询,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52212927/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com