IQueryable для списка <T> - PullRequest
1 голос
/ 13 мая 2011

Я знаю, что IQueryable не дает результата, а только построитель выражений, моя проблема в том, как на самом деле использовать его для выполнения запроса и вернуть набор в виде списка, чтобы иметь возможность связать его с сеткой.

  IQueryable query = _campaignManager.GetCampaign(filter, values);

  // this line returns error
  List<Campaign> campaigns = query.Cast<Campaign>().ToList();

  grdCampaigns.DataSource = campaigns;
  grdCampaigns.DataBind();

дополнительные сведения: GetCampaign ()

    public IQueryable GetCampaign(string filter, params object[] values)
    {
        string parameters = string.Empty;
        foreach (object obj in values)
        {
            parameters += obj.ToString() + ",";
        }

        parameters.Remove(parameters.Count() - 1, 1);

        var query = context.Campaigns.Where(filter, parameters)
           .Select("new(CampaignID,CampaignName)");

        return query;
    }

Я использую DynamicQueryable для динамических запросов linq

Метод расширения .Select для DynamicQueryable

     public static IQueryable Select(this IQueryable source, string selector, params object[] values)
    {
        if (source == null) throw new ArgumentNullException("source");
        if (selector == null) throw new ArgumentNullException("selector");
        LambdaExpression lambda = DynamicExpression.ParseLambda(source.ElementType, null, selector, values);
        return source.Provider.CreateQuery(
            Expression.Call(
                typeof(Queryable), "Select",
                new Type[] { source.ElementType, lambda.Body.Type },
                source.Expression, Expression.Quote(lambda)));
    }

IQueryable .Where () расширение

       public static IQueryable Where(this IQueryable source, string predicate, params object[] values)
    {
        if (source == null) throw new ArgumentNullException("source");
        if (predicate == null) throw new ArgumentNullException("predicate");
        LambdaExpression lambda = DynamicExpression.ParseLambda(source.ElementType, typeof(bool), predicate, values);
        return source.Provider.CreateQuery(
            Expression.Call(
                typeof(Queryable), "Where",
                new Type[] { source.ElementType },
                source.Expression, Expression.Quote(lambda)));
    }

спасибо ...

Ответы [ 2 ]

2 голосов
/ 21 апреля 2012

. .NET 4.0 и небольшая модификация динамической библиотеки позволяют достичь ожидаемого результата для: var campaigns = query.Cast<dynamic>().ToList(); или даже var campaigns = query.ToList();


Вот как это сделать:
Изменения:

public abstract class DynamicClass {

до:

public abstract class DynamicClass : System.Dynamic.DynamicObject {


Вот рабочий код с использованием модифицированной библиотеки:

var query = db.Customers.Where("City == @0 and Orders.Count >= @1", "London", 10).
            OrderBy("CompanyName").
            Select("New(CompanyName as Name, Phone)");

foreach (var val in query.Cast<dynamic>().ToList())
     Console.WriteLine(string.Format("Name: {0}, Phone: {1}", val.Name, val.Phone));


Мы также можем добавить перегруженный метод расширения в класс DynamicQueryable :

public static IQueryable<T> Select<T>(this IQueryable source, string selector, params object[] values)
{
    return Select(source, selector, values).Cast<T>();
}

Тогда мы сможем позвонить так:

var query = db.Customers.Where("City == @0 and Orders.Count >= @1", "London", 10).
            OrderBy("CompanyName").
            Select<dynamic>("New(CompanyName as Name, Phone)");

foreach (var val in query.ToList())
    Console.WriteLine(string.Format("Name: {0}, Phone: {1}", val.Name, val.Phone));


P.S .: От MSDN :

Любой объект может быть неявно преобразован в динамический тип.

Таким образом, мы сможем позвонить Cast<dynamic>() без предложенного изменения.

0 голосов
/ 13 мая 2011

IQueryable может относиться к типу T, например, IQueryable query = + CampaignManager.GetCampaign

, но так как вы используете IQueryable, вы можете использовать

var enumerator= c.GetEnumerator();
            while (enumerator.MoveNext())
            {
             //add these records to some collection say Collection or Campaign or Create any entity with Name and Id and then assign that collection to DataSource    
            }

я пытался, что он работает, вы можете продолжитьс этим.

...