linq 实体框架将IQueryable返回到两个表的联接中

bbuxkriu  于 2022-12-06  发布在  其他
关注(0)|答案(3)|浏览(198)

我想使用实体框架返回2个表中的数据,以及2个表中的列的选择,起初我没有太多的运气与一些简单的东西,如返回int的和字符串(即select new { id = t1.ID, other = t2.OtherData },因为在目的地转换匿名类型是麻烦的(目的地是我的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();
  }

除了方法的返回类型不正确之外,这一切都很好。我已经尝试了一些组合。不幸的是,当我从winform调用“byRecID”时,“SingleOrDefault”不可用,但在“byRecID”方法中可用,所以我不能只返回IQueryable,需要类型化IQueryable<SOMETHING IN HERE>(因为SingleOrDefault不是IQueryable的扩展,只有IQueryable<T>)。
我的问题...是否有一个语法的'SOMETHING IN HERE',让我指定它的一个连接的两个表行?
我想知道...为什么SingleOrDefault是方法内部的一个选项,而不是从我的winform调用时方法结果的一个选项?
基本上,我希望能够从我的winforms中调用干净的数据,而不用先转换成丑陋的匿名类型,然后使用反射(就像我返回匿名类型的原语时一样),但也不想生成一个类型,只是供我的byRecID方法使用。

2j4z5cfb

2j4z5cfb1#

在C#中,匿名类型最好用在你投射它们的同一个方法的作用域中。正如你自己所看到的它们不能用在定义方法之外。所以你不能从方法返回匿名类型(并保持它们的结构,你总是可以把它们作为对象返回,但这不是个好主意),这会使你的方法语法无效
最好的选择是将结果投影到根据需要指定的类。

public class TableJoinResult
{
   public Table1 Table1 { get; set; }
   public Table2 Table2 { get; set; }
}

您的查询:

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();
  }

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

bvn4nwqk

bvn4nwqk2#

1)创建描述结果的特定类。
2)参见1

iklwldmw

iklwldmw3#

我想避免创建一个特定的类或结构体。下面是一个冗长的方法来避免创建一个结构体/类。所以我在我的服务类中这样做了:-

List<KeyValuePair<string,int>> IWorkflowService.GetServiceRetention()
        {
           var serviceRetention =  from y in _context.SERVICES
                     join z in _context.SERVICE_SETTINGS on y.ID equals z.SERVICEID
                     select new { Service= y.SERVICE, Retention=z.RETENTION };//new KeyValuePair<string,int?>( y.SERVICE, z.RETENTION ));
            var list = new List<KeyValuePair<string, int>>();
            foreach (var obj in serviceRetention)
            {
                list.Add(new KeyValuePair<string, int>(obj.Service,Convert.ToInt32(obj.Retention)));
            }
            return list;
        }

我必须在我的控制器类中这样做:

List<KeyValuePair<string, int>> c = _service.GetServiceRetention();

            foreach (var obj in c)
            {
                 //The key contains service and value contains Rtention.
                  RecurringJob.AddOrUpdate(DELETE_SERVICE + obj.Key, () =>
                  Delete(obj.Key), //this is my function that does the actual process
               Cron.DayInterval(Convert.ToInt32(obj.Value)));
            }

我不确定这是否是最好的方法,但对我很有效。

相关问题