C# - 如何获取匿名类型,然后使用相同的选择器创建对象

本文关键字:然后 创建对象 选择器 类型 何获取 获取 | 更新日期: 2023-09-27 17:57:07

所以我正在尝试Azure的新DocumentDB。不幸的是,它不允许选择器类型。它不会让我做:

public IEnumerable<U> GetAll<U>(Expression<Func<T, U>> selector)
{
    return Client.CreateDocumentQuery<T>(Collection.DocumentsLink)
        .Select(selector)
        .AsEnumerable();
}

并将其用作:

// Doesn't work
return GetAll(t => new MyViewModel {
    Id = t.Id,
    Name = t.Name,
    Email = t.Email,
    Url = t.Url
});

说它只支持匿名类型。(我想因为它是相当新的,会在某个时候发生变化)。

我可以使用第二个选择来解决问题:

return GetAll(t => new {
    Id = t.Id,
    Name = t.Name,
    Email = t.Email,
    Url = t.Url
}).Select(t => new MyViewModel() {
    Id = t.Id,
    Name = t.Name,
    Email = t.Email,
    Url = t.Url
}).AsEnumerable();

然而,这是一种痛苦。

有没有办法两次使用相同的选择器并在第一次使其匿名?

C# - 如何获取匿名类型,然后使用相同的选择器创建对象

您会

注意到GetAll的签名包含Expression<Func<T, U>> selectorExpression部分表示此参数作为表达式树传递,而不是作为Func委托传递。这样做是为了让提供程序可以解析选择器并生成适当的数据库调用(通常是 SQL)来获取数据。

现在,当您使用特定的自定义类型时(在您的情况下MyViewModel - 提供程序遇到问题 - 它只是不知道如何将该类型转换为数据库调用。不过,它确实知道如何翻译匿名类型。

In then 返回一个IEnumerable<U>,因此 GetAll 返回的数据现在位于内存中,以便您可以执行 MyViewModel 类型的后续创建。无需再转换为数据库调用。

所以答案是这是设计使然。这不太可能成为未来的新功能。