简体   繁体   English

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

[英]C# - How do I get an anonymous type and then use the same selector to create an object?

So I'm trying out Azure's new DocumentDB. 因此,我正在试用Azure的新DocumentDB。 Unfortunately it doesn't allow selectors to a type. 不幸的是,它不允许选择器选择类型。 It won't let me do: 它不会让我做:

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

and use it as: 并将其用作:

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

It says it only supports anonymous types. 它说它仅支持匿名类型。 (I imagine since it's fairly new that will change at some point). (我想是因为它是一个相当新的东西,将来会有所改变)。

I can solve the problem using a second select: 我可以使用第二个选择来解决问题:

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();

However that is a pain. 但是,这很痛苦。

Is there a way to use the same selector twice and just make it anonymous the first time? 有没有办法两次使用相同的选择器,并且第一次使其匿名?

You'll notice the signature for GetAll contains Expression<Func<T, U>> selector . 您会注意到GetAll的签名包含Expression<Func<T, U>> selector The Expression part says that this argument is being passed as an expression tree and not as a Func delegate. Expression部分说此参数作为表达式树而不是作为Func委托传递。 It's done this way so that the provider can parse the selector and generate the appropriate database calls (often SQL) to fetch your data. 通过这种方式,提供者可以解析选择器并生成适当的数据库调用(通常是SQL)来获取数据。

Now, when you use a specific custom type - in your case MyViewModel - the provider hits a problem - it just doesn't know how to convert that type into the database calls. 现在,当您使用特定的自定义类型时(在您的情况下为MyViewModel ),提供程序遇到了问题-它只是不知道如何将该类型转换为数据库调用。 It does know how to translate an anonymous type though. 它确实知道如何翻译匿名类型。

In then returns an IEnumerable<U> so data returned by GetAll is now in memory so you can then perform the subsequent creation of the MyViewModel type. 然后,In返回IEnumerable<U>因此GetAll返回的数据现在已在内存中,因此您可以执行MyViewModel类型的后续创建。 There's no need to translate to database calls any more. 不再需要转换为数据库调用。

So the answer is that this is by design. 因此,答案是这是设计使然。 It is very unlikely that this will be a new feature in the future. 这在将来不太可能成为新功能。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM