我们需要使用数据传输对象来处理许多表格,因为它们非常大,很多列在我工作的上下文中没有用。
为了获得最佳性能,我不能读取完整的数据库实体,然后将其转换为数据传输对象。因此,我创建了一个 LINQ 扩展方法,在执行查询之前将其转换为数据传输对象。
调用扩展方法:
db.MyTable.Select(...).ToDto().ToList();
我的扩展方法:
public static IQueryable<MyTableDTO> ToDto(this IQueryable<MyTable> query)
{
return query.Select(x => new MyTableDTO
{
ID = x.ID,
Name = x.Name
});
}
这是一个可行的解决方案吗?还是有更好的做法?
第二个问题:不仅需要将IQueryable< MyTable >对象转换为DTO,还需要将MyTable对象转换。我为MyTable类创建了一个扩展方法:
public static MyTableDto ToDto (this MyTable x)
{
return new MyTableDto
{
ID = x.ID,
Name = x.Name
};
}
为什么我不能在我的第一个ToDto函数中使用这个函数呢? 例如:
public static IQueryable<MyTableDTO> ToDto(this IQueryable<MyTable> query)
{
return query.Select(x => x.ToDto());
}
更新
因为以下的研究,有一个进一步的问题出现。也有一些情况我们只想返回最少的字段以提高性能。
可以创建一个仓储类,在其中定义一个传递 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,
...
};
}