簡體   English   中英

具有泛型屬性的LINQ表達式

[英]LINQ expression with generic property

我的問題與這個問題有關: linq-expression-with-generic-class-properties

這次我想得到新創建的具有共同id的對象。 id實際上是外鍵,因此可以有不同的名稱。

我想出了以下內容:

public static IEnumerable<T> GetNew<TId, T>(IQueryable<T> objects, TId id, DateTime date, Expression<Func<T, TId>> idSelector) 
    where T : class, ISyncable<TId>
{
    return objects.Where(o => idSelector(o) == id && o.CreatedDate > date);
}

該方法將被調用如下:

var modified = GetNew(dbObjects, id, date, entity => entity.PersonId);

不幸的是我得到了錯誤:

'idSelector' is a variable but is used like a method.

傳遞給方法的表達式應該是這樣的:

objects.Where(o => o.PersonId == id && o.CreatedDate > date);

您需要構建一個表示條件的新表達式並將其傳遞給Where

public static IEnumerable<T> GetNew<TId, T>(IQueryable<T> objects, TId id, DateTime date, Expression<Func<T, TId>> idSelector)
    where T : class, ISyncable<TId>
{
    var paramExpr = Expression.Parameter(typeof(T));
    var idEqExpr = Expression.Equal(Expression.Invoke(idSelector, paramExpr), Expression.Constant(id));
    var createdPropExpr = Expression.Property(paramExpr, "CreatedDate");
    var gtExpr = Expression.GreaterThan(createdPropExpr, Expression.Constant(date));
    var andExpr = Expression.And(idEqExpr, gtExpr);

    var condExpr = Expression.Lambda<Func<T, bool>>(andExpr, paramExpr);

    return objects.Where(condExpr);
}

編輯:如果你知道idSelector是一個屬性表達式,你可以提取引用的屬性並創建一個新的屬性表達式而不是使用Invoke

var idProperty = (PropertyInfo)((MemberExpression)idSelector.Body).Member;
var idEqExpr = Expression.Equal(Expression.Property(paramExpr, idProperty), Expression.Constant(id));

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM