我有一個REST WebAPI,首先使用EntityFramework
數據庫。所有代碼產生斷EDMX
文件,實體,存儲庫的類和使用Linq PredicateBuilder進行文本搜索的連接字符串成員
我增加了一些過濾功能,其允許用戶添加通過查詢字符串擊中分貝時轉換爲LinqKit PredicateBuilder/Linq
表達式過濾結果條件API控制器等。
e.g. /api/Users?FirstName_contains=Rog
這將返回User.FirstName
成員中'Rog'的所有用戶。這使用PredicateBuilder
來動態構建適當的Linq
表達式,然後將其作爲Where
子句用於DbSet
。
例如:
var fieldName = "FirstName";
var value = "Rog";
var stringContainsMethod = typeof(string).GetMethod("Contains", new[] { typeof(string) });
var parameter = Expression.Parameter(typeof(User), "m");
var fieldAccess = Expression.PropertyOrField(parameter, fieldName);
var fieldType = typeof(User).GetProperty(fieldName, BindingFlags.IgnoreCase | BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public).PropertyType;
var expression = Expression.Lambda<Func<User, bool>>(Expression.Call(fieldAccess, stringContainsMethod, Expression.Constant(value, fieldType))
, parameter)
var andPredicate = PredicateBuilder.True<User>();
andPredicate = andPredicate.And(expression);
var query = Db.Users
.AsQueryable()
.AsExpandable()
.Where(andPredicate);
現在的問題。我希望客戶能夠根據成員構成匹配結果。
e.g. /api/Users?api_search[FirstName,LastName]=Rog
即搜索first name + last name
爲「羅格」的比賽,這樣我就可以搜索「羅傑釤」,並獲得頭名=羅傑和姓=史密斯的結果。
如果我用流利的查詢DbSet
它會是什麼樣子:
users.Where(u => (u.FirstName + " " + u.LastName).Contains("Rog"));
我所用是創造一個predicate/linq
表達式來處理字符串成員FirstName + " " + LastName
動態的串聯掙扎。
儘管t-sql中有一個CONCAT函數,但我不認爲EF(特別是L2SQL)功能支持這種翻譯。您應該首先使用.ToList()將所有條目取出,然後在內存中執行選擇。 – DevilSuichiro
嗯真的嗎?從我的旅行中,我很肯定上面流利的例子將轉化爲'WHERE FirstName +''+ LastName LIKE'%Rog%'的T-SQL。 –
爲什麼不'u => u.FirstName.Contains(query)|| u.LastName.Contains(查詢)'? – haim770