выберите анонимного делегата с помощью linq - PullRequest
3 голосов
/ 04 февраля 2011

Я знаю, что есть способ сделать это, но я бился головой о стену, пытаясь понять это. Это отлично работает:

private GenericRecord CreateGeneric(GenericRecord g, Member m)
{
    g.Member = m;
    return g;
}

public IList<GenericRecord> ReportFromDatabase(DateTime startDate, DateTime endDate)
{
    List<GenericRecord> returnRecords = new List<GenericRecord>();

    returnRecords.AddRange(from r in pjRepository.Records
                           join m in memberRepository.Members on r.SID equals m.MemberId.ToString()
                           where r.TransactionDate >= startDate && r.TransactionDate <= endDate
                           select CreateGeneric((GenericRecord)r, m));

    return returnRecords;
}

Но я знаю, что есть способ сделать это без функции CreateGeneric. Как выбрать встроенную функцию делегата?

returnRecords.AddRange(from r in pjRepository.Records
                       join m in memberRepository.Members on r.SID equals m.MemberId.ToString()
                       where r.TransactionDate >= startDate && r.TransactionDate <= endDate
                       select (delegate
                       {
                           GenericRecord g = (GenericRecord)r;
                           g.Member = m;
                           return g;
                       }));

Это дает мне это исключение:

The type of the expression in the select clause is incorrect. Type inference failed in the call to 'Select'.

Редактировать: Еще одна неудачная попытка

returnRecords.AddRange((from r in pjRepository.Records
                        join m in memberRepository.Members on r.SID equals m.MemberId.ToString()
                        where r.TransactionDate >= startDate && r.TransactionDate <= endDate
                        select new { r, m }).Select(x =>
                        {
                            GenericRecord g = (GenericRecord)x.r;
                            g.Member = x.m;
                            return g;
                        }));

Это дает мне:

Лямбда-выражение с телом оператора нельзя преобразовать в дерево выражений.

Ответы [ 2 ]

12 голосов
/ 04 февраля 2011

Попробуйте:

returnRecords.AddRange((from r in pjRepository.Records
                            join m in memberRepository.Members on r.SID equals m.MemberId.ToString()
                            where r.TransactionDate >= startDate && r.TransactionDate <= endDate
                            select new { r, m }).AsEnumerable().Select(x =>
                            {
                                GenericRecord g = (GenericRecord)x.r;
                                g.Member = x.m;
                                return g;
                            }));

Ключ в том, что функция AsEnumerable ().Это берет IQueryable и возвращает IEnumerable, который за кулисами вызывает оценку дерева выражений поставщиком Linq.Это предотвращает попытку библиотеки Linq преобразовать лямбду второго Select в часть дерева выражений (что, по ее словам, не может);второй выбор вместо этого выполнит свое преобразование фактической коллекции im-памяти, созданной путем оценки дерева выражений IQueryable.Поскольку требуется, чтобы запрос был оценен до того, как оператор все равно завершится (поэтому все элементы могут быть добавлены в returnRecords), значительных различий в производительности не должно быть.

0 голосов
/ 14 апреля 2014
Seem like this is what you are looking at:
class Bila
    {
        public string Name;
        public List<string> Adresses;
    }
     var justNumbers = Enumerable.Range(0, 10);
Func<int,List<string>> foo = delegate(int j)
    {
        List<string> lst = new List<string>();
        for (int kk = 0; kk < j; kk++)
        {
            lst.Add("String_" + kk.ToString());
        }
        return lst;
    };
var zilla3 = (from x in justNumbers
              select new Bila
              {
                  Name = "Name_" + x.ToString(),
                  Adresses = foo(x),
              }).ToArray();
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...