C#EF从另一个表中查找数据的最佳方法

时间:2017-04-09 21:01:42

标签: c# entity-framework linq

我遇到的情况我必须编写应用程序,其中我从tableA获取大量记录然后对于每个记录我必须对tableB进行查找以获取额外信息(获取另外3列)。

TableA是一个小表(< 1000条记录),但tableB要大得多。此外,它们位于同一DB服务器上的单独DB中。

什么是优化它的最佳方法?

没有选项可以将所有记录从tableB中获取到对象列表然后对其进行操作,而是需要针对tableA对每个tableB元素(对象)运行LINQ查询。这是我的MVC的一部分,所以请你提供一个解决方案草案,高级描述,而不是提供代码。

EDIT  tableA记录在显示之前需要对tableB进行“丰富”,有效的是这可能是+/- 500 tableA记录要对tableB进行查找。另外,限制是我只能读写tableB..no选项来编写程序等

3 个答案:

答案 0 :(得分:0)

您可以在其中一个数据库中创建一个视图,该数据库组合了表A和B中的数据。然后将您的实体映射到该视图。看看https://www.mssqltips.com/sqlservertip/1990/how-to-use-sql-server-views-with-the-entity-framework/

答案 1 :(得分:0)

如果没有看到您的模型和查询,很难提供准确的答案。但是,最好的开始是在数据库中(我假设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)为每个数据库生成数据库上下文。让我们称他们为DbContextADbContextB

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)。

答案 2 :(得分:0)

  

您应该创建一个类意味着.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来显示您的数据。