[英]How to implement method with expression parameter c#
I want to create a method like this: 我想创建一个这样的方法:
var result = database.Search<EntityType>(x=>x.Name, "Entity Name field value");
result = database.Search<EntityType>(x=>x.Id, "Entity Id field value");
result = database.Search<EntityType2>(x=>x.Id, "Entity2 Id field value");
result = database.Search<EntityTypeAny>(x=>x.FieldAny, "EntityAny FieldAny value");
How can I implement this method? 我该如何实现这个方法?
You can turn a selector and value into a predicate using Expression.Equal
: 您可以使用
Expression.Equal
将选择器和值转换为谓词:
static IQueryable<TSource> Search<TSource, TValue>(
this IQueryable<TSource> source,
Expression<Func<TSource,TValue>> selector,
TValue value)
{
var predicate = Expression.Lambda<Func<TSource,bool>>(
Expression.Equal(
selector.Body,
Expression.Constant(value, typeof(TValue))
), selector.Parameters);
return source.Where(predicate);
}
Then you just need to do something like: 然后你只需要做一些事情:
var result = database.SomeEntities.Search(x => x.SomeProp, "value");
If you want to do it from the database , then that depends on what the database is ; 如果你想从数据库中做到这一点,那么这取决于数据库是什么; for example, with LINQ-to-SQL you could add an additional method:
例如,使用LINQ-to-SQL,您可以添加其他方法:
static IQueryable<TSource> Search<TSource, TValue>(
this System.Data.Linq.DataContext database,
Expression<Func<TSource, TValue>> selector,
TValue value) where TSource : class
{
IQueryable<TSource> source = database.GetTable<TSource>();
return Search(source, selector, value);
}
and use: 并使用:
var result = database.Search<SomeEntity, string>(x => x.SomeProp, "value");
frankly I think it is clearer to use the database.SomeEntities
version, though. 坦率地说,我认为使用
database.SomeEntities
版本更清楚。
I can only think of this (with 2 generic arguments) 我只能想到这个(有两个通用参数)
public static IEnumerable<TModel> Search<TModel, TValue>(
Expression<Func<TModel, TValue>> expression,
TValue value
)
{
return new List<TModel>();
}
usage 用法
var result = Search<EntityType, int>(x => x.Id, 1);
var result2 = Search<EntityType, string>(x => x.Name, "The name");
you can replace TValue with object to avoid the second generic argument, but I would stick with this. 你可以用对象替换TValue以避免第二个泛型参数,但我会坚持这一点。
Btw. 顺便说一句。 this works great in conjunction with this little helper
这与这个小助手一起很好用
public static class ExpressionHelpers
{
public static string MemberName<T, V>(this Expression<Func<T, V>> expression)
{
var memberExpression = expression.Body as MemberExpression;
if (memberExpression == null)
throw new InvalidOperationException("Expression must be a member expression");
return memberExpression.Member.Name;
}
}
Now you can get the Name of the Property (Id oder Name) in this example by calling 现在,您可以通过调用获取此示例中的属性名称(Id order Name)
var name = expression.MemberName();
do you want types to dynamic 你想要类型动态吗?
public ReturnType Read<ReturnType>(string FieldName, object dfVal)
{
if (Res.IsDBNull(Res.GetOrdinal(FieldName)))
return dfVal;
try {
return (ReturnType)Res.GetValue(Res.GetOrdinal(FieldName));
} catch (Exception ex) {
return dfVal;
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.