簡體   English   中英

通過Linq to OData中的關鍵字段來運算符“ IN”

[英]Operator “IN” by key field in Linq to OData

大家下午好! 我正在嘗試在SQL中轉換請求:

SELECT *
FROM TABLE1
WHERE TABLE1.ID IN (SELECT ID FROM TABLE2)

到LINQ to OData。 至於ODAta協議不支持“ IN”, WHERE部分必須類似於TABLE1.ID=1 OR TABLE1.ID=2 OR ... ,我嘗試編寫通用方法,該方法將id作為輸入列表並以這種方式返回LINQ的正確表達式:

public static Expression<Func<T,bool>> Lambda<T>(this Expression expr ,List<int> ids)
    {
        ParameterExpression argParam = Expression.Parameter(typeof(T), "rep");
        Expression<Func<T, bool>> lambda = code => 1 == 0;
        var lambdaPred = Expression.Lambda<Func<T, bool>>(lambda.Body, argParam);
        var attr = (DataServiceKeyAttribute)typeof(T).GetCustomAttribute(typeof(DataServiceKeyAttribute));
        string keyName;
        try
        {
            keyName = attr.KeyNames.FirstOrDefault();//get name of key attribute
        }
        catch
        {
            return null;
        }
        foreach (int id in ids)
        {
            var property = typeof(T).GetProperty(keyName);
            Expression<Func<T, bool>> lambdatemp = code => (int)property.GetValue(code) == id;                               
            var tmp = Expression<Func<T, bool>>.Or(lambdaPred.Body, lambdatemp.Body);                
            lambdaPred = Expression.Lambda<Func<T, bool>>(tmp, argParam);
        }
        return lambdaPred;
    }

此方法的用法:

Expression<Func<Client, bool>> lambda = code => 1 == 0;
var query = lambda.Body.Lambda<Client>(ids);
var retr = clientRepository.Retrieve(query).ToList();

但在運行時出現錯誤:

Microsoft.Data.Services.Client.dll中發生類型'System.NotSupportedException'的異常,但未在用戶代碼中處理

附加信息:表達式((((((False或(Convert(Int32 Id.GetValue(code))== 1044))或(Convert(Int32 Id.GetValue(code))== 8102))或(Convert(Int32 Id.GetValue(code))== 5997))或(Convert(Int32 Id.GetValue(code))== 7761))或(Convert(Int32 Id.GetValue(code))== 15455))不支持。

您知道解決此問題的任何方法嗎?

您編寫的通用方法還不清楚(包括簽名和實現)。 據我了解,想法是建立這樣的表達

x => x.Id == Id1 || x.Id == Id2 || ....

這是通過使用Expression.EqualExpression.OrElse的方法的一種可能方式

public static class PredicateHelper
{
    public static Expression<Func<T, bool>> In<T>(this Expression<Func<T, int>> idSelector, IEnumerable<int> ids)
    {
        Expression body = null;
        foreach (var id in ids)
        {
            var operand = Expression.Equal(idSelector.Body, Expression.Constant(id));
            body = body == null ? operand : Expression.OrElse(body, operand);
        }
        return body != null ? Expression.Lambda<Func<T, bool>>(body, idSelector.Parameters) : null;
    }
}

用法示例與您的示例相同

var idFilter = PredicateHelper.In((Client c) => c.Id, ids);
var result = clientRepository.Retrieve(idFilter).ToList();

暫無
暫無

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

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