如何创建可重用的Entity Framework投影表达式?

时间:2016-01-13 16:34:21

标签: c# .net entity-framework linq-to-entities entity-framework-6

在我的数据库中,有几十列的表格:

Table MyEntity: int Id string Name string Email ...dozens of other columns I never use in this project

EF生成的类具有这些额外列的属性,而简单的查询会浪费地获取所有这些额外的列。

相反,我想要一个瘦的类,如下:

class MyEntity { public int Id; public string Name; public string Email; }

当我查询时,我想创建我的瘦对象的实例,显然,我可以这样做:

from x in MyEntity
select new MyEntity {Id = x.Id, Name = x.Name, Email = x.Email };

但我做了很多,每次输入属性变得非常繁琐(而且容易出错,因为我可以忘记一个)。

所以我试着做这样的事情:

from x in MyEntity
select x.ToLiteEntity();

但是我不确定如何编写ToLiteEntity以便创建一个表达式并添加到查询中,以便它知道只从数据库中选择所需的列。我怎么能这样做?

2 个答案:

答案 0 :(得分:2)

您可以将其抽象为数据库上方的图层。如果要检索“精简”对象,请调用单独的方法:

public IQueryable<MyEntity> GetLiteMyEntities(DbContext c, string Name) // your implementation of DbContext, not actually DbContext
{
    return from me in c.MyEntity 
        select new MyEntity {Id = x.Id, Name = x.Name, Email = x.Email };
}

编辑:如果您需要过滤不想返回的其他字段,可以先编写过滤查询,然后使用接受 IQueryable的方法:

public IQueryable<MyEntity> GetLiteMyEntities(IQueryable<MyEntity> query)
{
    return from me in query 
        select new MyEntity {Id = x.Id, Name = x.Name, Email = x.Email };
}

// build your filter first
from x in MyEntity 
where x.someSpecialID == 42
select x;

// then pass it to get your lite object
var lite = GetLiteMyEntities(x);

更好的是,将其作为扩展方法:

public IQueryable<MyEntity> GetLiteMyEntities(this IQueryable<MyEntity> query)
{
    return from me in query 
        select new MyEntity {Id = x.Id, Name = x.Name, Email = x.Email };
}

var lite = (from x in MyEntity 
where x.someSpecialID == 42
select x).GetLiteMyEntities();

答案 1 :(得分:1)

您可以使用AutoMapper中的Queryable Extensions

  

.ProjectTo()将告诉AutoMapper的映射引擎   向IQueryable发出一个select子句,它将通知实体   它只需要查询Item的Name列的框架   表,就像手动将IQueryable手动投影到一样   带有Select子句的OrderLineDTO。