实体框架返回两个表的连接的 IQueryable

Nin*_*oel 3 c# linq entity-framework-6

我想使用实体框架从 2 个表中返回数据,以及 2 个表的选定列,起初我对简单的东西不太走运,比如返回 int 和字符串(即select new { id = t1.ID, other = t2.OtherData },作为铸造匿名type 在目的地很麻烦(目的地是我的 winform),所以我想到了只返回两个表行的想法......

所以像这样:

  public static IQueryable<{Table1,Table2}> byRecID(Guid recID, MyContext DBContext)
  {
      return (from i1 in DBContext.Table1
             join j1 in DBContext.Table2 on i1.GroupID equals j1.GroupID
             where i1.RecID.Equals(RecID)
             select new { i1, j1 }).SingleOrDefault();
  }
Run Code Online (Sandbox Code Playgroud)

这一切都很好,除了方法的返回类型不正确。我尝试了几种组合。不幸的是,当我从 winform 调用“byRecID”时,“SingleOrDefault”不可用,但在“byRecID”方法中可用,所以我不能只返回IQueryable,需要输入IQueryable<SOMETHING IN HERE>(因为SingleOrDefault不是 的扩展IQueryable,仅IQueryable<T>) .

我的问题......是否有“这里的东西”的语法,让我指定它的两个表行的连接?

我想知道...当从我的 winform 调用时,为什么 SingleOrDefault 是方法内部的一个选项,而不是方法结果的选项?

基本上我希望有一些东西可以从我的 winforms 调用干净的数据,而不需要转换为可怕的匿名类型然后使用反射(就像我返回匿名类型的原语一样),但也不想产生一个只供我使用的类型byRecID方法。

vas*_*ski 6

在 c# 中,匿名类型最好用于投影它们的同一方法的范围内。正如您所见,它们不能在定义方法之外使用。所以你不能从方法中返回匿名类型(并保持它们的结构,你可以将它们作为对象返回,但这不是一个好主意),这会使你的方法语法无效

最好的选择是将结果投影到为您的需要指定的类。

public class TableJoinResult
{
   public Table1 Table1 { get; set; }
   public Table2 Table2 { get; set;}
}
Run Code Online (Sandbox Code Playgroud)

您的查询:

 public static IQueryable<TableJoinResult> byRecID(Guid recID, MyContext DBContext)
  {
      return (from i1 in DBContext.Table1
             join j1 in DBContext.Table2 on i1.GroupID equals j1.GroupID
             where i1.RecID.Equals(RecID)
             select new TableJoinResult { Table1= i1, Table2 = j1 }).SingleOrDefault();
  }
Run Code Online (Sandbox Code Playgroud)

有关匿名类型的更多信息https : //msdn.microsoft.com/en-us/library/bb397696.aspx