从单个对象中选择作为表达式

本文关键字:表达式 选择 单个 对象 | 更新日期: 2023-09-27 17:50:38

如何将表达式应用于单个项?现在我有一个表达式,可以用于支持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);

我正在寻找的是一种重用该表达式的方法,以便当我在方法中收到包含作者的Book时,我可以这样做:

public BookDto SampleMethod(Book propertiesIncludedBook)
{
    //this does not compile because Book does not have a Select method.
    return propertiesIncludedBook.Select(AsBookDto);
}

从单个对象中选择作为表达式

大多数LINQ扩展在IEnumerableIQueryable上工作,在您的情况下,您需要的只是一个正常的函数/委托,但如果您想保持与LINQ使用相同的语法,只需编写自己的扩展方法:

public static TOutput SelectSingle<TInput, TOutput>(
    this TInput obj,
    Expression<Func<TInput, TOutput>> expression)
{
    return expression.Compile()(obj);
}

用作:

public BookDto SampleMethod(Book propertiesIncludedBook)
{
    return propertiesIncludedBook.SelectSingle(AsBookDto);
}

错误检查被省略了,但是正如你所看到的,像这样直接使用它并没有这样的好处:

public BookDto SampleMethod(Book propertiesIncludedBook)
{
    return AsBookDto.Compile()(propertiesIncludedBook);
}

编辑用单独的Func<Book, BookDto>分隔表达式定义,但使表达式本身相当无用。移除。