查询这些表最有效的Linq语句是什么?



在这个例子中,我有一个下面的表,其中一列为"受限访问"。我有另一张表,里面有访问信息。使用linq连接下面的表的最好方法是什么?

我们有主表,我们将其命名为reports

的报告
tbody> <<tr>2
idreportisRestricted
10
b1
3c1

假设你已经把你的导航属性都连接好了(一个Report有一个ICollection of Access)等等,你可以问:

var q = context.Reports.Where(r => r.IsRestricted == 0 || r.Accesses.Any(a => a.Company == currentCompany))

EF将执行必要的连接等操作。如果你正在使用EF5,想看看它写了什么SQL,在Where运行后暂停调试器,看看Q变量的DebugView属性。我认为这是一个左连接到一个子查询只是谷歌,要求左连接不是空的(但很难记住它们是如何翻译的)

如果您还没有在模型中的表之间建立任何关系,它可能需要看起来更像:

var q = context.Reports.Where(r => r.IsRestricted == 0 || context.Accesses.Any(a => r.Report == a.Report && a.Company == currentCompany))

这将变成一个sql,它使用一个协调的EXISTS来检查公司是否存在于该报告的access表中

在任何一种情况下,我认为DB可能会以类似的方式计划和执行查询,但如果你知道哪个更执行,你将不得不比赛你的马!

如果我们从普通对象开始,我们可以:

using System;
using System.Linq;

public class Program
{
public static void Main()
{
var reports = new []
{
new { Id = 1, Report = "a", IsRestricted = 0 },
new { Id = 2, Report = "b", IsRestricted = 1 },
new { Id = 3, Report = "c", IsRestricted = 1 }
};

var accesses = new [] 
{
new { Id = 1, Company = "google", Report = "b" },
new { Id = 2, Company = "alphabet", Report = "c" }
};

var currentCompany = "google";

var list = reports
.Where(r => r.IsRestricted == 0)
.Select(r => r.Report)
.Concat(accesses
.Where(a => a.Company == currentCompany)
.Select(a => a.Report)
)
.Distinct()
.ToList();

System.Console.WriteLine(list.Aggregate((a, b) => a + "," + b));
}
}

这将打印a,b

由于你的问题集中在LINQ上,我认为如果你能在从数据库读取和操纵记录后提供视图/数据结构/上下文,这将有助于其他人回答你的问题。