【问题标题】:HowTo use Dynamic linq with an index instead of a property name如何使用带有索引而不是属性名称的动态 linq
【发布时间】:2012-01-26 20:07:21
【问题描述】:

我有一个带有对象的 ICollection:

private ObservableCollection<ViewItem> items;

viewItems 没有属性。数据将通过带有

的索引访问
public  object this[int index] {
   get{ .... }
   set {....}
}

我有一个通用的过滤类。具有属性的 linq 可以正常工作。我使用(仅重要代码):

Queryable = CreateQueryable((IEnumerable<object>)mItemsSource.SourceCollection, ItemType);
mQuery = Queryable.Where(filterString).Cast<object>();
ilteredCollection = mQuery.ToList();

与:

private static IQueryable CreateQueryable(IEnumerable<object> collection, Type itemType)
{
        if (itemType == null) return null;

        var queryableList = collection.AsQueryable();
        return queryableList.Provider.CreateQuery(
            Expression.Call(
                typeof(Queryable), "Cast",
                new Type[] { itemType },
                queryableList.Expression));
}

所以我可以使用过滤器字符串,例如:Id&gt;10Name="abc" 其中IdName 是属性名称。

但我在另一个集合中也有对象,它只能通过索引访问。所以我有一个 where 字符串,例如:

[0]>10 or [1]="abc"

我没有找到任何解决方案。我能找到的唯一提示是使用:

new(it([idx] as Type)

其中idx 是元素索引,Type 是该元素的类型

例如

[0]>10 --> new(it[0] as object)>10

但我得到的错误是:

{"运算符 '=' 与操作数类型 'DynamicClass1' 和 'Int32' 不兼容"}

在我的过滤器中使用字符串,例如:

new(it[0] as object)>"10" 

比错误是:

{"运算符 '=' 与操作数类型 'DynamicClass1' 和 'string' 不兼容"}

那么 - 我该如何解决这个问题。因为这是一个通用的过滤器类,所以我也不知道类型。所以在 as 语句中我只能使用 object 或类似的东西。

我希望任何人都可以帮助我。也许 C# 4.0 的 dynamic 关键字会有所帮助?? 顺便说一句,一种解决方法是使用索引器在每个类中实现一个包装器,但这将是很多愚蠢的工作。这是一个真正的程序员不喜欢的东西;)。我相信有一个解决方案!

【问题讨论】:

  • 请查看this 并阅读更新!

标签: c# casting dynamic-linq


【解决方案1】:

加油!!

首先——如何访问当前实例?

当解析带有单个未命名参数的 lambda 表达式时,未命名参数的成员自动在表达式字符串的范围内,并且可以使用关键字 it 整体引用未命名参数给出的当前实例。例如,

customers.Where("Country = @0", country);

等价于

customers.Where("it.Country = @0", country);

以上概念已经解释here.

根据上面的解释,我们现在可以访问 indexer 属性,因为它[@0] 其中@0 是要传递的索引的值,如下所述。

//考虑下面的类

public class Product
{
    private NameValueCollection collection = new NameValueCollection();
    public string Company { get; set; }
    public string Distributor { get; set; }
    public int ID { get; set; }
    ...

    public string this[string index]
    {
        get { return collection[index]; }
        set { if(!string.IsNullOrEmpty(value)) collection[index]=value; }
    }
}

//主代码

        List<Product> list = new List<Product>();
        Product product = new Product() { Company = "Nestle", Distributor = "xyz", ID = 1 };
        product["Name"] = "Maggi";
        list.Add(product);
        var filteredList = list.AsQueryable().Where("it[@0]=@1", "Name", "Maggi"); //Accessing the current item by indexer property

        foreach (Product productItem in filteredList)
        {
            Console.WriteLine(productItem.Company);
        }

希望对你有帮助!! :)

【讨论】:

    【解决方案2】:

    您对new 关键字的使用是错误的。 它不会投射对象(as 也不会)。

    关键字new 用于创建具有指定属性的匿名类的新对象。 因此new(it[idx] as Type) 将创建具有属性Type 的新对象,其值为it[idx]。相当于 C# 的:new { Type = this[idx] }

    正如我在Dynamic linq: Is there a way to access object data by index? 中已经指出的那样,您需要按以下方式转换它:Int32(it[0]) &gt; 10 用于您的伪查询[0] &gt; 10

    【讨论】:

      猜你喜欢
      • 2019-04-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-12-07
      • 1970-01-01
      相关资源
      最近更新 更多