получить глубокую собственность для лямбда-выражения - PullRequest
0 голосов
/ 09 марта 2012

У меня есть такой код:

CaseHeaderComparer CaseComparer = new CaseHeaderComparer();
List<CaseHeader> CasesToProcess = new List<CaseHeader>();

foreach (GroupField fld in Fields)
{
    //get the field property - ie. Division
    System.Reflection.PropertyInfo piField = typeof(CaseHeader).GetProperty(fld.GroupFieldType.PropertyName);
    //get the item property - ie. DivisionID
    System.Reflection.PropertyInfo piItem = piField.PropertyType.GetProperty(fld.GroupFieldType.ValueMember);

    foreach (CaseHeader ch in ToProcess)
    {
        object chItem = piField.GetValue(ch, null);
        Guid ItemID = chItem != null ? (Guid)piItem.GetValue(chItem, null) : Guid.Empty;

        if (fld.Items.Select(i => i.ItemID).Contains(ItemID))
        {
            CasesToProcess.Add(ch);
        }
    }
    ToProcess = ToProcess.Except(CasesToProcess, CaseComparer).ToList();
}

К которому я хотел бы перейти, чтобы использовать linq и lambdas - вчера я довольно близко подошел с некоторой помощью к этому:

List<CaseHeader> ToProcess = ....;
CaseHeaderComparer CaseComparer = new CaseHeaderComparer();
IEnumerable<CaseHeader> CasesToProcess = new BackingSheetCaseHeader[] { };
foreach (GroupField fld in Fields)
{
    //get the field property - ie. Division
    System.Reflection.PropertyInfo piField = typeof(CaseHeader).GetProperty(fld.GroupFieldType.PropertyName);
    //get the item property - ie. DivisionID
    System.Reflection.PropertyInfo piItem = piField.PropertyType.GetProperty(fld.GroupFieldType.ValueMember);

    CasesToProcess.Union(
        ToProcess
            .Where(c => fld.Items.Select(i => i.ItemID)
                .Contains((piField.GetValue(c, null) != null ? (Guid)piItem.GetValue(piField.GetValue(c, null), null) : Guid.Empty)))
                , CaseComparer);
}

это работает, но кто-то указал, что я мог бы сделать что-то вроде этого ..

var hdr = typeof(CaseHeader);
var param = Expression.Parameter(hdr);
var cond = Expression.Condition(
    Expression.NotEqual(param, Expression.Constant(null, hdr))
,   Expression.Property(param, fld.GroupFieldType.PropertyName) <<-- but this needs to go 2 deep.. as above the item property..
,   Expression.Constant(Guid.Empty)
);
var lambda = (Func<MyCaseObj,Guid>)Expression.Lambda(cond, param).Compile();

тогда я мог бы сделать

var CasesToProcess = (from csh in CasesInGroup 
    where lambda(csh).In(fld.Items.Select(i => i.ItemID)) 
    select csh);

но глубокий бит 2 вводит меня в заблуждение как и выше, мне нужно добраться до свойства fld.GroupFieldType.ValueMember свойства fld.GroupFieldType.PropertyName CaseHeader. значение первого уровня может быть нулевым ..

Может кто-нибудь дать мне несколько советов, или где-нибудь, чтобы прочитать об этом

спасибо

1 Ответ

1 голос
/ 09 марта 2012

Может случиться так, что вам вообще не нужно создавать Expression вручную . Компилятор C # может переводить лямбда-выражения в Func<> s и Expression<Func<>> s. Обе следующие работы:

        var func = (Func<int, bool>)(i => i == 2);
        var expression = (Expression<Func<int, bool>>)(i => i == 2);

, после чего expression.Compile() - это Func<int,bool> с тем же поведением, что и func! Так что попробуйте просто

var expression = (Expression<Func<MyCaseObj,Guid>>)
    (c => fld.Items.Select(i => i.ItemID)
          .Contains((piField.GetValue(c, null) != null 
                     ? (Guid)piItem.GetValue(piField.GetValue(c, null), null) 
                     : Guid.Empty))
    );

и возьми его оттуда.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...