C# 我可以重构linq语句中的范围变量吗?
我有一个EntityFramework3.5项目,我在其中使用TPH继承。我的两个具体类型在它们自己的DAO类中,包含一个选择器,该选择器将实体类投影到DTO中。然而,这两个具体的类与另一个表有相似的关系,我使用let语句来清楚地标识它。我的问题是,我是否可以以某种方式重构这个let语句,因为当我创建更多继承的具体类时,我觉得我违反了DRY StudentDAO.cs:C# 我可以重构linq语句中的范围变量吗?,c#,linq,entity-framework,C#,Linq,Entity Framework,我有一个EntityFramework3.5项目,我在其中使用TPH继承。我的两个具体类型在它们自己的DAO类中,包含一个选择器,该选择器将实体类投影到DTO中。然而,这两个具体的类与另一个表有相似的关系,我使用let语句来清楚地标识它。我的问题是,我是否可以以某种方式重构这个let语句,因为当我创建更多继承的具体类时,我觉得我违反了DRY StudentDAO.cs: var myDTO = from x in context.Students let address = (from a in
var myDTO = from x in context.Students
let address = (from a in x.addresses where a.active == true select a).FirstOrDefault()
select new StudentDTO { id = x.id, studentname = x.studentname, address = a.address};
博士生:
var myDTO = from x in context.Professors
let address = (from a in x.addresses where a.active == true select a).FirstOrDefault()
select new ProfessorDTO { id = x.id, professorname = x.studentname, address = a.address};
那么,有没有一种方法可以从这两个查询中重构地址呢?简短的回答:恐怕没有什么可以轻松做到的。问题是您需要参数化查询。但是,查询需要表示为表达式树,以便将其转换为SQL或EF使用的任何内容。不幸的是,C没有提供任何优雅的方式来构建表达式树
详细回答:不久前,我写了一篇C文章,解释了如何使用一些技巧——您可以使用表达式树并将其拼接到参数化查询中。因此,原则上,您可以使用本文中的技术创建一个方法,该方法接受表达式树中不断变化的部分,然后组合查询
我将使用LINQ to SQL中使用的类型,因为我对它比较熟悉,但我相信原理应该是一样的:
IQueryable<R> GetInfo<T>(IQueryable<T> source, // e.g. context.Students
Expression<Func<T, IQueryable<Address>>> getAddr, // x => x.adresses
Expression<Func<T, Address, R>> getRes // (x, a) => new StudentDTO { ... }
return
from x in source.AsExpandable()
let address = (from a in getAddr(x).Expand() where a.active == true
select a).FirstOrDefault()
select getRes(x, a).Expand();
}
// The use would look like this
var res = GetInfo(context.Professors, x => x.addresses, (x, a) => new
ProfessorDTO { id = x.id, professorname = x.studentname, address = a.address });
因此,总结一下,C和LINQ没有提供任何内置的支持,这将使它变得更容易。但是,通过一些努力,您可以编写由表达式树的某些部分参数化的查询。在您的例子中,它使代码变得更短,重复性更少,但它使代码变得更复杂,您还需要使用我所引用的库,它提供了可扩展性和可扩展性
在这种情况下,恐怕这不值得努力。但是如果C vNext ^x能够为类似这样的事情提供一些更优雅的支持,那就太好了:-链接的文章是dead@Fredou我会更新链接-应该是