我的模型如下所示
public class Country
{
public int Id {get; set;}
public string Name {get; set;}
}
public class User
{
public int Id{get; set;}
public string FirstName {get; set;}
public string LastName {get; set;}
public string Email {get; set;}
}
public class Company
{
public int Id{get; set;}
public string Name {get;set;}
public string City {get; set;}
public string Address1 {get; set;}
public string Address2 {get; set;}
[ForeignKey("Country")]
public int CountryId{get; set;}
public Country Country{get; set;}
public ICollection<CompanyUsers> CompanyUsers {get; set;}
}
public class CompanyUsers
{
public int Id{get; set;}
[ForeignKye("Company")]
public int CompanyId {get; set;}
[ForeignKye("User")]
public int UserId {get; set;}
public Country Country{get; set;}
public User User{get; set;}
}
我想讓用戶能夠通過Country, Company or User class 除了 Id 屬性中定義的任何屬性來搜索公司記錄
我嘗試查看此SO 討論,但它不處理導航屬性。有人可以幫助我構建動態 where 子句,包括導航屬性中的屬性。
有了這個實作,我只能做如下
myContext.CompanyEntity
.Where(FilterLinq<CompanyEntity>
.GetWherePredicate(searchParams))
.ToList();
public class SearchField
{
public string Key { get; set; }
public string Value { get; set; }
}
uj5u.com熱心網友回復:
從您指出的答案擴展這個想法并不復雜。
您需要更改假設,以便 SerchField 中的屬性名稱可以包含屬性路徑的定義,例如Company.CityorCompany.Country.Name以及 property FirstName。你需要處理它:
所以不僅僅是像這樣簡單的屬性:
Expression columnNameProperty = Expression.Property(pe, fieldItem.Name);
你需要處理財產鏈:
Expression columnNameProperty = GetPropertyExpression(pe, fieldItem.Name);
Expression GetPropertyExpression(Expression pe, string chain){
var properties = chain.Split('.');
foreach(var property in properties)
pe = Expression.Property(pe, property);
return pe;
}
基本上,這段代碼的作用是pe在創建屬性鏈的每個回圈上應用屬性而不是先前的修改變數。物體框架將處理它并創建適當的連接。這僅適用于單個關系,不適用于集合。
因此該答案的修改后的代碼如下所示:
public class FilterLinq<T>
{
Expression GetPropertyExpression(Expression pe, string chain)
{
var properties = chain.Split('.');
foreach(var property in properties)
pe = Expression.Property(pe, property);
return pe;
}
public static Expression<Func<T, Boolean>> GetWherePredicate(params SearchField[] SearchFieldList)
{
//the 'IN' parameter for expression ie T=> condition
ParameterExpression pe = Expression.Parameter(typeof(T), typeof(T).Name);
//combine them with and 1=1 Like no expression
Expression combined = null;
if (SearchFieldList != null)
{
foreach (var fieldItem in SearchFieldList)
{
//Expression for accessing Fields name property
Expression columnNameProperty = GetPropertyExpression(pe, fieldItem.Name);
//the name constant to match
Expression columnValue = Expression.Constant(fieldItem.Value);
//the first expression: PatientantLastName = ?
Expression e1 = Expression.Equal(columnNameProperty, columnValue);
if (combined == null)
{
combined = e1;
}
else
{
combined = Expression.And(combined, e1);
}
}
}
//create and return the predicate
return Expression.Lambda<Func<T, Boolean>>(combined, new ParameterExpression[] { pe });
}
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/qianduan/414423.html
標籤:
