Многоразовое использование сложного метода linq
От: snaphold  
Дата: 27.08.15 06:10
Оценка:
У меня много страниц на сайте, где представление такое:

кол-во объектов в виде ссылкы и далее по клику уже выгружаются сами объекты.

Есть Функция которая считает кол-во объектов в базе и идентичная функции которая выгружает сами объекты, за исключением того, что первая еще делает Count() в конце.
Т.к. функция не простая сочетает в себе GroupJoin, SelectMany неохота делать 2 разных метода.

Можно ли сделать один метод для 2 случаев, чтобы не открывать 2 контекста?
т.е. хотелось бы иметь что-то типа конструктора метода или делегата и чтобы к нему можно было добавлять всякие Count
Re: Многоразовое использование сложного метода linq
От: Sinix  
Дата: 27.08.15 06:13
Оценка: +1
Здравствуйте, snaphold, Вы писали:

S>Можно ли сделать один метод для 2 случаев, чтобы не открывать 2 контекста?

S>т.е. хотелось бы иметь что-то типа конструктора метода или делегата и чтобы к нему можно было добавлять всякие Count

А чем не подходит
static IEnumerable<SomeClass> SomeCondition(this IEnumerable<SomeClass> source) { /* reusable code */}

// ...

var c = someData.SomeCondition().OrderBy(...)
?
(с IQueryable, понятное дело, тоже работает).
Re[2]: Многоразовое использование сложного метода linq
От: snaphold  
Дата: 27.08.15 07:03
Оценка:
Здравствуйте, Sinix, Вы писали:

S>Здравствуйте, snaphold, Вы писали:


S>>Можно ли сделать один метод для 2 случаев, чтобы не открывать 2 контекста?

S>>т.е. хотелось бы иметь что-то типа конструктора метода или делегата и чтобы к нему можно было добавлять всякие Count

S>А чем не подходит

S>
S>static IEnumerable<SomeClass> SomeCondition(this IEnumerable<SomeClass> source) { /* reusable code */}

S>// ...

S>var c = someData.SomeCondition().OrderBy(...)
S>
?

S>(с IQueryable, понятное дело, тоже работает).

забыл про расширетили, но они тут не особо помогут ибо идет left join на другую таблицу

т.е. есть таблица Data в которой есть столбец City и есть таблица CityPhones.
надо вывести кол-во и собственно потом сами города у которых нет соотвествия в таблице CityPhones

 using (var ctx = new Context())
            {                 
                var CityPhonesCount = ctx.Data.Select(a => a.City)                                                                
                                                                .GroupJoin(ctx.CityPhones.Select(c => c.Name),
                                                                           d => d,
                                                                           e => e,
                                                                           (d, i) => new { d, i = i.DefaultIfEmpty() })
                                                                .SelectMany(z => z.i.Select(e => new { d = z.d, e }))
                                                                .Where(n => n.e == null)
                                                                .Select(n => n.d)
                                                                .Distinct()
                                                                .Count();
             }
Re: Многоразовое использование сложного метода linq
От: Doc Россия http://andrey.moveax.ru
Дата: 27.08.15 08:16
Оценка:
Здравствуйте, snaphold, Вы писали:

S>т.е. хотелось бы иметь что-то типа конструктора метода или делегата и чтобы к нему можно было добавлять всякие Count


Т.е. изобрести свой linq хотите (просто уровень абстракции будет другой)? В принципе ничего не мешает это сделать (метод который вернет IQueryable<T> к которому надо будет еще добавить ToArray(Async)/Count(Async) и т.д.

Но я бы пошел наверное по другому пути — класс Query, что-то вроде (грубый код).
public class MyDataQuery {

    public async Task<int> CountAsync() 
    {
        using (var context = new MyDbContext()) 
            return await this.GetBaseQuery(context).CountAsync();
    }

    public async Task<IEnumerable<MyData>> ExecuteAsync() 
    {
        using (var context = new MyDbContext()) 
            return  await this.GetBaseQuery(context).ToArrayAsync();
    }

    private IQueryable<MyData> GetBaseQuery(DbContext context) {
        // общая часть запроса        
        return context.MyDataTable.Where(... );
    }
}


Все это еще можно и в базовый QueryBase<T> класс завернуть (чтобы каждый раз не писать методы CountAsync и ExecuteAsync).
Re[2]: Многоразовое использование сложного метода linq
От: snaphold  
Дата: 27.08.15 14:02
Оценка:
Здравствуйте, Doc, Вы писали:

Doc>Здравствуйте, snaphold, Вы писали:


S>>т.е. хотелось бы иметь что-то типа конструктора метода или делегата и чтобы к нему можно было добавлять всякие Count


Doc>Т.е. изобрести свой linq хотите (просто уровень абстракции будет другой)? В принципе ничего не мешает это сделать (метод который вернет IQueryable<T> к которому надо будет еще добавить ToArray(Async)/Count(Async) и т.д.


Doc>Но я бы пошел наверное по другому пути — класс Query, что-то вроде (грубый код).

Doc>
public class MyDataQuery {

Doc>    public async Task<int> CountAsync() 
Doc>    {
Doc>        using (var context = new MyDbContext()) 
Doc>            return await this.GetBaseQuery(context).CountAsync();
Doc>    }

Doc>    public async Task<IEnumerable<MyData>> ExecuteAsync() 
Doc>    {
Doc>        using (var context = new MyDbContext()) 
Doc>            return  await this.GetBaseQuery(context).ToArrayAsync();
Doc>    }

Doc>    private IQueryable<MyData> GetBaseQuery(DbContext context) {
Doc>        // общая часть запроса        
Doc>        return context.MyDataTable.Where(... );
Doc>    }
Doc>}


Doc>Все это еще можно и в базовый QueryBase<T> класс завернуть (чтобы каждый раз не писать методы CountAsync и ExecuteAsync).


а в 4.0 можно что-то подобное замутить? или надо аналог await писать?
Re[3]: Многоразовое использование сложного метода linq
От: Doc Россия http://andrey.moveax.ru
Дата: 28.08.15 02:37
Оценка:
Здравствуйте, snaphold, Вы писали:

S>а в 4.0 можно что-то подобное замутить? или надо аналог await писать?


1) Не использовать async и вызывать все синхронно

или

2) Install-Package Microsoft.Bcl.Async в проект под .NET4 позволит и там использовать async/await
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.