无法找到一个动态的对象属性或字段 [英] Can't find property or field on a dynamic object

查看:189
本文介绍了无法找到一个动态的对象属性或字段的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用动态的LINQ 的做一些数据库查询和它的工作真的很好达现在。我可以传递一个字符串到选择来选择,像这样的字段:

I using Dynamic Linq to do some database queries and it's working really well up to now. I can pass a string to a Select to select fields like so:

var output = myDatabaseTable.Select("Foo, Bar");

例如。当你传递一个字符串变量,而不是硬编码字符串的力量显然是。我运行到现在的问题是,该库使用的IEnumerable 而不是的IEnumerable< T> ,因为,很明显,它无法知道 T 到运行时。我用这个来选择数据,并最终返回给客户端,它工作得很好吐出原始数据,但现在我希望能够返回数据前做一些更多的处理,并需要获得查询上运行数据库第一。我可以做这样的事情:

For example. The power obviously being when you pass a string variable rather than hardcoded strings. The problem I'm running into now is that the library using IEnumerable instead of IEnumerable<T> because, obviously, it can't know T until runtime. I'm using this to select data and eventually return it to a client and it works fine for spitting out raw data, but now I want to be able to do some more processing before returning the data and that requires getting the query to run on the database first. I can do something like this:

var materializedResults = output.Cast<dynamic>().ToList();

和,这将使查询运行。但问题是,一旦我做到了这一点,看来我也不能使用动态LINQ了。例如,如果我做了这样的事情:

And that will make the query run. But the problem is, once I've done that, it seems I can't use dynamic linq anymore. For example, if I did something like this:

var foos = materializedResults.Select("Foo");



我现在得到了 System.Linq.Dynamic.ParseException 的消息字段'富'存在类型的无财产'对象'(注:我可以在调试器中看到 materializedResults 并实际拥有所有预期的属性)。

I now get a System.Linq.Dynamic.ParseException with the message No property of field 'Foo' exists in type 'Object' (Note: I can see in the debugger that the materializedResults does actually have all the expected properties).

所以铸造后列表这样我就可以通过它潜在的迭代和修改一些价值观,我不能再查询。

So after casting to a List so I can potentially iterate through it and modify some of the values, I can no longer query it.

所以我的问题是,我怎么能采取动态查询(与选择,GROUP BY,由字符串提供等顺序),物化的结果,然后实际处理这些动态结果呢?

So my question is, how can I take a dynamic query (with select, group by, order by etc provided as strings), materialize the results and then actually process those result dynamically?

我想也许如果我能转换为实际的类型而不是动态它可能工作,所以我尝试这:

I thought maybe if I could cast to the actual type rather than dynamic it might work, so I tried this:

var d = output.Cast<dynamic>().ToList();
MethodInfo method = typeof(Enumerable).GetMethod("Cast", new[] {typeof(IEnumerable)});
method = method.MakeGenericMethod(d.First().GetType());
output = method.Invoke(d, new[] {d}) as IEnumerable;



这是丑陋的,需要我投了两次。第一次到动态这样我就可以再次获得第一个项目类型为该类型。

Which is ugly and requires me to cast twice. The first time to dynamic so I can get the type from the first item then again to that type.

推荐答案

如果您 YourStuff.Cast<动态> .ToList(),您将收到的IEnumerable<对象> ,并没有财产的类型对象

If you do YourStuff.Cast<dynamic>.ToList(), you will receive IEnumerable<object>, and there is no property Foo on the type object.

您可能会问的问题,你怎么能获得的IList< TheActualType> ?你可以这样来做:

The question you might be asking, how can you get IList<TheActualType>?! You can do it this way:

// for IEnumerable
public static IList ToAnonymousList(this IEnumerable enumerable)
{
    var enumerator = enumerable.GetEnumerator();
    if (!enumerator.MoveNext())
        throw new Exception("?? No elements??");

    var value = enumerator.Current;
    var returnList = (IList) typeof (List<>)
        .MakeGenericType(value.GetType())
        .GetConstructor(Type.EmptyTypes)
        .Invoke(null);

    returnList.Add(value);

    while (enumerator.MoveNext())
        returnList.Add(enumerator.Current);

    return returnList;
}

    // for IQueryable
    public static IList ToAnonymousList(this IQueryable source)
    {
        if (source == null) throw new ArgumentNullException("source");

        var returnList = (IList) typeof (List<>)
            .MakeGenericType(source.ElementType)
            .GetConstructor(Type.EmptyTypes)
            .Invoke(null);

        foreach (var elem in source)
            returnList.Add(elem);

        return returnList;
    }



这是一个简单的扩展方法,它可以在以后使用,因为这样的:

It's a simple extension method that can later be used, as such:

var test = (new[]
{
    new
    {
        Property1 = "10",
        Property2 = "10",
        Property3 = 1
    }
}
.Select("New(Property1, Property2)"))
.ToAnonymousList();

这篇关于无法找到一个动态的对象属性或字段的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆