Pin*_*nzi 9 c# linq entity-framework dto
我们必须为我们的许多表使用数据传输对象,因为它们非常大,并且许多列对我正在使用的上下文没用.
为了获得最佳性能,我无法读取完整的数据库实体,并在之后将其转换为dtos.因此,我创建了一个linq扩展方法,在执行查询之前将其转换为dtos.
延期召唤方法:
db.MyTable.Select(...).ToDto().ToList();
Run Code Online (Sandbox Code Playgroud)
我的扩展方法:
public static IQueryable<MyTableDTO> ToDto(this IQueryable<MyTable> query)
{
return query.Select(x => new MyTableDTO
{
ID = x.ID,
Name = x.Name
});
}
Run Code Online (Sandbox Code Playgroud)
这是一个可行的解决方案还是有更好的做法?
第二个问题:不仅需要将IQueryable <MyTable>对象转换为dtos,还必须转换MyTable对象.我为MyTable类创建了一个扩展方法:
public static MyTableDto ToDto (this MyTable x)
{
return new MyTableDto
{
ID = x.ID,
Name = x.Name
};
}
Run Code Online (Sandbox Code Playgroud)
为什么我不能在我的第一个ToDto功能中使用此功能?喜欢:
public static IQueryable<MyTableDTO> ToDto(this IQueryable<MyTable> query)
{
return query.Select(x => x.ToDto());
}
Run Code Online (Sandbox Code Playgroud)
由于下面的研究,还有一个问题.在某些情况下,我们希望仅为高性能问题返回最少的字段.
可以创建一个存储库类,您可以在其中定义一个参数,以传递一个Func,其中包含应由查询返回的字段(如下所述).然后可以创建一个类(下面示例中的MyServiceClass),您可以在其中为不同的返回实体调用相同的存储库方法.但这是一个好的做法还是什么是更好的解决方案呢?
public class MyTableRepository<T>
{
public List<T> GetMyTable(String search1, String search2, Func<MyTable, T> selectExp)
{
using(var db = new Context())
{
return db.MyTable.Where(x => x.A == search1 ...).Select(selectExp).ToList();
}
}
}
public class MyServiceClass
{
public List<MyTableEntitySimple> GetMyTableEntitySimple(String search1...)
{
MyTableRepository<MyTableEntitySimple> rep = new ...
return rep.GetMyTable(search1, ToMyTableEntitySimple);
}
public List<MyTableEntity> GetMyTableEntity(String search1...)
{
MyTableRepository<MyTableEntity> rep = new ...
return rep.GetMyTable(search1, ToMyTableEntity);
}
Func<MyTable, MyTableEntitySimple) ToMyTableEntitySimple = x => new MyTableEntitySimple
{
ID = x.ID,
Name = x.Name
};
Func<MyTable, MyTableEntity) ToMyTableEntity = x => new MyTableEntitySimple
{
ID = x.ID,
Name = x.Name,
Field3 = x.Field3,
Field4 = x.Field4,
...
};
}
Run Code Online (Sandbox Code Playgroud)
因为您的Linq to Entities提供程序不知道如何将方法调用转换为SQL语句.作为您的问题的解决方案,您可以使用lambda表达式而不是扩展方法:
Func<MyTable, MyTableDTO> selectExp=x => new MyTableDTO{
ID = x.ID,
Name = x.Name
});
//Pass the lambda expression as a paremter
public static IQueryable<MyTableDTO> ToDto(this IQueryable<MyTable> query, Func<MyTable, MyTableDTO> selectExpr)
{
return query.Select(selectExpr);
}
Run Code Online (Sandbox Code Playgroud)
或者正如@Timothy在评论中所建议的那样,你也可以使用Automapper.使用DTO映射实体类后,可以执行以下操作:
using AutoMapper.QueryableExtensions;
public static IQueryable<MyTableDTO> ToDto(this IQueryable<MyTable> query)
{
return query.ProjectTo<MyTableDTO>();
}
Run Code Online (Sandbox Code Playgroud)
您可以在此页面中找到更多信息.
对于我的拳头解决方案,也许您可以创建一个通用的扩展方法:
public static IQueryable<T> ToDto<TSource,T>(this IQueryable<TSource> query, Func<TSource, T> selectExpr)
{
return query.Select(selectExpr);
}
Run Code Online (Sandbox Code Playgroud)
关于第二个,我仍然认为恕我直言,你可以配置你的映射:
// Configure AutoMapper
Mapper.CreateMap<MyTable, MyTableDTO>()
.ForMember(dest => dest.YourNewName1, opt => opt.MapFrom(src => src.YourGermanName1))
.ForMember(dest => dest.YourNewName2, opt => opt.MapFrom(src => src.YourGermanName2));
Run Code Online (Sandbox Code Playgroud)
您可以在此链接中找到关于此主题的精彩文章.
| 归档时间: |
|
| 查看次数: |
1601 次 |
| 最近记录: |