C# EF 在另一个表中查找数据的最佳方法
Posted
技术标签:
【中文标题】C# EF 在另一个表中查找数据的最佳方法【英文标题】:C# EF best way to lookup data from one table within another 【发布时间】:2017-09-04 19:58:18 【问题描述】:我遇到了一种情况,我必须编写应用程序,从 tableA
获取大量记录,然后对于每条记录,我必须对 tableB
进行查找以提取额外信息(获取另外 3 列)。
TableA
是一个小表(tableB 要大得多。此外,它们位于同一数据库服务器上的不同数据库中。
优化它的最佳方法是什么?
没有选项可以将所有记录从 tableB 中获取到对象列表中然后对其进行操作,而是需要针对 tableB
对每个 tableA
元素(对象)运行 LINQ 查询。这是我的 MVC 的一部分,所以请您提供一份解决方案草稿,在高层次上进行描述,而不是提供代码。
编辑 tableA 记录在显示之前需要针对 tableB 进行“丰富”,实际上这可能是 +/- 500 条 tableA 记录要针对 tableB 进行查找。此外,限制是我只有对 tableB 的读取访问权限..没有编写程序的选项等
【问题讨论】:
我忘了提一下,tableA 记录在显示之前需要针对 tableB 进行“丰富”,实际上这可能是 +/- 500 条 tableA 记录要针对 tableB 进行查找跨度> 【参考方案1】:您可以在其中一个数据库中创建一个视图,将表 A 和 B 中的数据组合在一起。然后将您的实体映射到该视图。看看这个https://www.mssqltips.com/sqlservertip/1990/how-to-use-sql-server-views-with-the-entity-framework/
【讨论】:
对不起,伙计,我没有告诉这个,但我只读取了数据库的访问权限。我可以操作的一个地方是我的应用程序。【参考方案2】:没有看到您的模型和查询,很难提供准确的答案。但是,最好的开始是在数据库中(我假设 SQL Server 2012+)。
根据您的描述,生成的查询应该看起来非常简单,如下所示:
SELECT A.*, B.Col1, B.Col2, B.Col3
FROM Db1.dbo.TableA AS A
JOIN Db2.dbo.TableB AS B ON B.Id = A.FkToBId
根据this question 及其接受的答案,从同一数据库中选择与从另一个数据库中选择在同一实例中 之间没有太大区别。
如果TableB
很大,你应该避免表扫描,所以下面的索引应该是一个好的开始:
CREATE INDEX IDX_TableB_Id ON TableB (Id) INCLUDE (Col1, Col2, Col3)
但是,如果架构被正确规范化,则查找键也应该是主键,并且不需要此索引。我认为如果是集群的话,可能会带来额外的好处。
当然,您的 LINQ 可能会生成稍微不同的查询。如果是这种情况,请编辑您的问题并包含表架构、LINQ 和生成的查询。
[编辑]
使用SqlQuery
是一种选择,但我正在考虑另一种方式:
1) 为每个数据库生成一个数据库上下文。让我们称他们为DbContextA
和DbContextB
2) 仅从TableB
获取所需信息,将其存储在字典中以便快速查找并用于聚合查询。
var ids = DbContextA.TableA.AsNoTracking().Select(item => item.FkToBId).ToList();
var bInfo = DbContextB.TableB.AsNoTracking()
.Where(item => ids.Contains(item.id))
.ToDictionary(
item => item.Id,
item => new item.Col1, item.Col2, item.Col3
);
var aggrInfo = DbContextA.TableA.AsNoTracking()
.ToList()
.Select(item => new
AField = item,
Col1 = bInfo[item.FkToBId],
Col2 = bInfo[item.FkToBId],
Col3 = bInfo[item.FkToBId]
;
如果这不能有效地提供所需,SqlQuery 仍然是唯一的选择,因为数据库上下文不能同时处理两个数据库 (source)。
【讨论】:
如果我可以使用 Join 对两个实体(DB)进行一个 LINQ 查询,那将是可行的 ..但我不确定这是否可以成为这里的一个选项,到目前为止还没有什么经验.. 您可以使用DbContext.Database.SqlQuery<T>()
扩展方法。您传入此 anwser 中提到的自定义 SQL 查询,并将类型参数 T
设置为具有与查询输出相同的属性的类型。 example
使用加入让它工作。我必须做的一个小改动是确保两个表都在相同的数据库上下文中。【参考方案3】:
您应该创建一个类表示 .cs 文件并添加所需的 TableA 和 TableB 的所有列。
让我们看看示例这里我有两个表类别和子类别我想要类别的名称并想要显示列表。
public class SubCategory
public int Id get; set;
public string Name get; set;
public string Image get; set;
public Nullable<bool> Isdisplay_ get; set;
public Nullable<int> CatId get; set;
public string CatName get; set;
var data = (from t in db.SubCategories
join ts in db.Categories on t.CatId equals ts.CategoryId
select new a1 = t.SubId, a2 = t.SubImage, a3 = t.SubIsdisplay_, a4 =
t.SubName, a5 = ts.CategoryName ).ToList();
List<SubCategory> p1 = new List<SubCategory();
foreach (var i in data)
SubCategory p2 = new SubCategory();
p2.Id = i.a1;
p2.Name = i.a4;
p2.Image = i.a2;
p2.Isdisplay_ = i.a3;
p2.CatName = i.a5;
p1.Add(p2);
return p1;
现在您可以使用列表 p1 来显示您的数据。
【讨论】:
以上是关于C# EF 在另一个表中查找数据的最佳方法的主要内容,如果未能解决你的问题,请参考以下文章
在另一个表 Laravel 中查找具有数据透视表中所有 id 的记录
Microsoft Access 中的选择查询在另一个表中查找返回错误结果的记录