4

在我的数据库,有表有几十列:如何创建可重用的实体框架投影表达式?

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,这样就产生了表达是被添加到查询,以便它知道只从数据库中选择需要的列。我怎样才能做到这一点?

+0

如果你从来没有在项目中使用的其他列在所有的,为什么在项目开始与引用它们?还是他们没有数据库中的默认值,所以你不能没有他们创建新的行? –

+0

由于EF模型生成器创建它们。我可以删除它们,但有时我必须重新生成,并且我会丢失这些修改。 –

+0

如果您的数据库模式与EF模型不匹配,最好不要使用模型生成器。 –

回答

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(); 
+0

这非常好,但缺点是Lite对象不仅要包含所有要返回的字段,还要包含任何您可能想在Where子句中使用但不返回的内容。 –

+0

@JoshuaFrank看到我的编辑,你可以编写查询并使用它们,直到需要时才会执行('ToList',迭代等)。 – DrewJordan

1

您可以使用Queryable Extensions从AutoMapper

的.ProjectTo()会告诉AutoMapper的映射引擎 发出SELECT子句中的IQueryable的,将通知实体 框架,它只需要查询项目 表的名称列,同就好像您手动将您的IQueryable投影到具有Select子句的OrderLineDTO 。

+0

使用派生类(多态)时,我遇到了这个问题。首先得到一个堆栈溢出异常,然后切换到使用ProjectUsing方法,但它无法使用抽象基类。 –