Как передать делегат расширения C # Select () или выражение в репозиторий? - PullRequest
4 голосов
/ 28 октября 2010

Каждый проектирует время от времени:

 var c = dc.Products.Select( p => new {p.id, p.name});
 // results in c having properties of .id and .name

Что, если я хочу изменить этот метод в методе.Как бы я передал параметр Select?

var c = myFunction( p => new {p.id, p.name});

Product myFunction( ??? myLambda)
{
    var c = dc.Products.Select( myLambda);

    var result = new Product();
    foreach( var myproperty in //property in myLambda)
    {
        result.XX // property that matches, set it equal to myproperty
    }
}

Очевидно, что мне нужно больше размышлять об отражении.:)

Ответы [ 2 ]

3 голосов
/ 28 октября 2010

Вы можете хотя бы взглянуть на любые существующие определения LINQ, например http://msdn.microsoft.com/en-us/library/bb548891.aspx

Так что вам нужно Func<TSource, TResult> myLambda

Чтобы быть точным:

TResult myFunction<TResult>(Expression<Func<Product, TResult>> myLambda)

или

IEnumerable<TResult> myFunction<TResult>(Expression<Func<Product, TResult>> myLambda)

UPD : согласно комментарию @tvanfosson - код немного изменился.

2 голосов
/ 28 октября 2010

Тип параметра должен быть примерно таким: Expression<Func<Product,object>>.Кроме того, я думаю, что вам нужно, чтобы ваша функция возвращала IEnumerable<Product> с установленными свойствами.

IEnumerable<Product> myFunction( Expression<Func<Product,object>> selector )
{
    var products = new List<Product>();
    foreach (var c in dc.Products.Select( selector ))
    {
        var product = new Product();
        foreach (var property in c.GetType().GetProperties())
        {
            var productProperty = typeof(Product).GetProperty( property.Name );
            productProperty.SetValue( product, property.GetValue( c, null ) );
        }
        products.Add( product );
    }
    return products;
}

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

IEnumerable<T> ProductPartial<T>( Func<Product,T> selector ) where T : new
{
      return dc.Products.ToList().Select( selector );
}

используется как

var pricing = repository.ProductPartial( p => new PricingModel( p ) );

Примечание. Подумав немного, если вы собираетесь вернуть отдельную модель, я думаю, что выможет потребоваться реализовать запрос, прежде чем вы все равно сможете выполнить преобразование в модель.В этом случае Func<Product,T>, вероятно, является наиболее подходящим - я включил явный ToList (), чтобы убедиться, что запрос реализован первым, чтобы выбор не провалился.Если бы это было предложение Where, это было бы иначе.Хотя это немного менее эффективно с точки зрения передачи данных (вы извлекаете все свойства), я все же предпочитаю использовать конкретную модель, если вам кажется, что вам нужно поместить выбор в репозиторий.Поскольку вы выбираете только часть свойств, кажется неправильным притворяться, что у вас есть настоящий экземпляр Product, а на самом деле это не так.

...