我想使用Entity Framework从2个表中返回数据,并选择2个表中的列,起初我对简单的事情没什么好运,比如返回int和字符串(即。{{ 1}},因为在目的地(目的地是我的winform)上,匿名类型很麻烦,所以我想到了只返回两个表行...
这样的事情:
select new { id = t1.ID, other = t2.OtherData }
这一切都很好除了方法的返回类型不正确。我试过几个组合。不幸的是,当我从winform调用“byRecID”时,“SingleOrDefault”不可用,但是在'byRecID'方法中可以使用IS,所以我不能只返回 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();
}
,需要输入IQueryable
(因为IQueryable<SOMETHING IN HERE>
不是SingleOrDefault
的扩展名,只有IQueryable
)。
我的问题......是否有一个'SOMETHING IN HERE'的语法,可以让我指定它的两个表行的连接?
我想知道......为什么SingleOrDefault是一个选项INSIDE方法,但不是从winform调用时方法结果的选项?
基本上我希望有一些允许来自我的winforms的干净数据调用的东西,而不会使用反射(比如当我返回匿名类型的基元)时使用隐藏的匿名类型,但也不希望仅为了生成类型使用我的IQueryable<T>
方法。
答案 0 :(得分:2)
1)创建一个描述结果的特定类。
2)见1
答案 1 :(得分:2)
在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
答案 2 :(得分:0)
我想避免创建特定的类或结构。 以下是一种避免创建结构/类的冗长方法。 所以我在我的服务类中做到了这一点: -
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)));
}
我不确定这是否是最好的方法,但对我有用。