[英]Entity Framework returning IQueryable of join of two tables
我想使用Entity Framework从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>
)。
我的问题...“这里有东西”是否有一种语法,可以让我指定其两个表行的连接?
而且我想知道...当从Winform调用SingleOrDefault时,为什么在方法中包含选项而不是方法结果的选项?
基本上,我希望能够允许从winforms进行干净的数据调用,而不必转换为可怕的匿名类型,然后使用反射(例如当我返回匿名类型的基元时),但是我也不想产生一个供我使用的Type byRecID
方法。
在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
1)创建一个描述您的结果的特定类。
2)查看1
我想避免创建特定的类或结构。 下面是避免创建结构/类的冗长方法。 所以我在我的服务班上做了这个:
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)));
}
我不确定这是否是最好的方法,但是对我有用。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.