【发布时间】:2014-03-16 08:07:04
【问题描述】:
如何将表达式应用于单个项目?现在我有一个表达式可以在列表或任何支持 Select 扩展方法的集合上使用。我也想将该功能扩展到单个对象。这里有一个例子来说明我的意思:
private static readonly Expression<Func<Book, BookDto>> AsBookDto =
x => new BookDto
{
Title = x.Title,
Author = x.Author.Name,
Genre = x.Genre,
Description = x.Description,
Price = x.Price,
PublishDate = x.PublishDate
};
有了这个表达式,我可以做这样的事情:
IQueryable<BookDto> books = db.Books.Include(b => b.Author)
.Where(x => x.AuthorId == authorId).Select(AsBookDto);
我正在寻找的是一种重用该表达式的方法,以便在我收到包含作者的书时,我可以执行以下操作:
public BookDto SampleMethod(Book propertiesIncludedBook)
{
//this does not compile because Book does not have a Select method.
return propertiesIncludedBook.Select(AsBookDto);
}
【问题讨论】:
-
这是否意味着您实际上从数据库中检索了完整的
Book对象?通常,使用 DTO 类的方式是直接投影到它们,就像您在第一个示例中所做的那样。做你要求的是可能的,但可能不是你想要的,因为它的行为方式不同:例如,x.Author.Name会突然导致NullReferenceException如果x.Author == null(即使作者是在数据库中设置)。你能解释一下你想何时以及如何使用你的SampleMethod吗? -
是的,我尝试这样做的原因是因为我使用 FirstOrDefault 从数据库中取回了一个项目(包括将在表达式中使用的所有对象),然后取决于检索到的对象的状态,我将选择对其应用哪个表达式以将其转换为 Dto。假设检索到的对象具有 Inviter 和 Invitee 属性(pocos),现在根据状态我将使用 AsInviterToDto 或 AsInviteeToDto。
-
另一种方法是使用 AutoMapper。此时,您可以在代码中选择要应用的映射。