Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/linq/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 我可以重构linq语句中的范围变量吗?_C#_Linq_Entity Framework - Fatal编程技术网

C# 我可以重构linq语句中的范围变量吗?

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

我有一个EntityFramework3.5项目,我在其中使用TPH继承。我的两个具体类型在它们自己的DAO类中,包含一个选择器,该选择器将实体类投影到DTO中。然而,这两个具体的类与另一个表有相似的关系,我使用let语句来清楚地标识它。我的问题是,我是否可以以某种方式重构这个let语句,因为当我创建更多继承的具体类时,我觉得我违反了DRY

StudentDAO.cs:

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我会更新链接-应该是