C# 有可能在lambda函数中建立一个动力场吗?
我有这样一个函数:C# 有可能在lambda函数中建立一个动力场吗?,c#,entity-framework,lambda,automapping,C#,Entity Framework,Lambda,Automapping,我有这样一个函数: public CountryDto FindCountryByName(string name) { Country country = _countryRepository.GetAll().Where(g => g.Name.ToLower().Trim() == name.ToLower().Trim()).FirstOrDefault(); var dto = _mapper.Map<Country, CountryDto>(cou
public CountryDto FindCountryByName(string name)
{
Country country = _countryRepository.GetAll().Where(g => g.Name.ToLower().Trim() == name.ToLower().Trim()).FirstOrDefault();
var dto = _mapper.Map<Country, CountryDto>(country);
return dto;
}
及
我不记得在哪里找到这个函数,我正在使用它根据给定的属性名生成LINQ查询,请注意,您可以将搜索函数“Equals”更改为“Contains”或“StartsWith”:
///
///创建查询,在类T的给定属性中搜索与值匹配的结果
///
公共静态IQueryable CreateSearchQuery(IQueryable queryable,string PropertyName,string value),其中T:class
{
IQueryable query=queryable;
列表表达式=新列表();
ParameterExpression参数=表达式参数(类型为(T),“p”);
MethodInfo Equals_Method=typeof(string).GetMethod(“Equals”,new[]{typeof(string)});
MethodInfo ToString_Method=typeof(object).GetMethod(“ToString”);
//遍历除继承属性以外的所有属性
foreach(PropertyInfo prop,类型为(T).GetProperties(BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public)
.Where(x=>x.PropertyType==typeof(string)//类型string的属性
||x.Name==PropertyName)
{
ConstantExpression value_expression=表达式.常量(值,类型(字符串));
MemberExpression member\u expression=expression.PropertyOrField(参数,prop.Name);
//组合ToString()和Equals()方法
MethodCallExpression callChain=Expression.Call(Expression.Call(member\u Expression,ToString\u Method),Equals\u Method,value\u Expression);
Add(callChain);
}
if(expressions.Count==0)
返回查询;
表达式或_表达式=表达式[0];
for(int i=1;i
您的“按名称查找”功能看起来已经很奇特了。您不想改为按特定属性值查找吗?所以。其中(t=>t.Name==Name)
我展示了两个示例。也许你知道我想要什么。好吧,那么你想按属性值搜索。为什么不直接传递一个表达式呢?e、 g.Find(表达式x.Name==“Foo”)
这仅适用于字符串属性。如果传入类型上不存在的属性名称,则很容易中断。您可以添加更多属性类型并进行空检查。当然可以,但是如果要使用int
或DateTime
属性,该怎么办?如果有人换了T班怎么办?在运行时之前,您不会知道存在问题,这使得此操作非常危险。对,我们不传递属性名称,而是传递propertyinfo,这将使函数更加准确。如果您对此函数进行一些更改以消除这些缺点,我将非常感谢,这样我就可以在我的项目中对其进行重构
public IEnumerable<T> GetAll()
{
return table.ToList();
}
public IEnumerable<T> FindByName(string objname, string name)
{
return table.Where(t => t.GetType(objname) == name);
}
Country country = _countryRepository.FindByName("CountryName", name);
AlbumTrack track = _albumtrackRepository.FindByName("SongTitle", songTitle);
///<summary>
/// Create query that search in given property of class T for matching results with value
/// </summary>
public static IQueryable<T> CreateSearchQuery<T>(IQueryable<T> queryable, string PropertyName, string value) where T : class
{
IQueryable<T> query = queryable;
List<Expression> expressions = new List<Expression>();
ParameterExpression parameter = Expression.Parameter(typeof(T), "p");
MethodInfo Equals_Method = typeof(string).GetMethod("Equals", new[] { typeof(string) });
MethodInfo ToString_Method = typeof(object).GetMethod("ToString");
//Iterate through all properties Except inherited ones
foreach (PropertyInfo prop in typeof(T).GetProperties(BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public)
.Where(x => x.PropertyType == typeof(string) //properties of type string
|| x.Name == PropertyName))
{
ConstantExpression value_expression = Expression.Constant(value, typeof(string));
MemberExpression member_expression = Expression.PropertyOrField(parameter, prop.Name);
//Combine ToString() and Equals() methods
MethodCallExpression callChain = Expression.Call(Expression.Call(member_expression, ToString_Method), Equals_Method, value_expression);
expressions.Add(callChain);
}
if (expressions.Count == 0)
return query;
Expression or_expression = expressions[0];
for (int i = 1; i < expressions.Count; i++)
{
or_expression = Expression.OrElse(or_expression, expressions[i]);
}
Expression<Func<T, bool>> expression = Expression.Lambda<Func<T, bool>>(or_expression, parameter);
return query.Where(expression);
}