C# 创建与LINQ到SQL兼容的表达式,该表达式通过属性名称访问属性
我想知道你们中是否有人对如何解决这个问题有想法 假设有下面的类C# 创建与LINQ到SQL兼容的表达式,该表达式通过属性名称访问属性,c#,linq,reflection,linq-to-sql,C#,Linq,Reflection,Linq To Sql,我想知道你们中是否有人对如何解决这个问题有想法 假设有下面的类 public class Person { public string Description {get; set;} //... } 我想创建一个表达式,该表达式可以传递到LINQ to SQL中LINQ的Where方法中的LINQ的Where方法,例如: Expression<Func<Person, bool>> expression = x => x.Description.C
public class Person
{
public string Description {get; set;}
//...
}
我想创建一个表达式,该表达式可以传递到LINQ to SQL中LINQ的Where
方法中的LINQ的Where
方法,例如:
Expression<Func<Person, bool>> expression = x => x.Description.Contains("foo");
Expression=x=>x.Description.Contains(“foo”);
这里真正的问题是,在运行时之前,我不知道要检查哪个字段。属性的名称以字符串形式提供(在本例中,它将是“Description”,但可以是“Description2”,也可以是
Person
类的任何其他属性)。我不能直接在表达式本身中使用反射来获取属性值(通过使用GetType
,GetProperty
等),因为表达式在LINQ to SQL中传递到Where
时无法工作,因为它无法转换为SQL代码。提前谢谢 看看这个最小的示例,所需的属性将被访问并与另一个字符串进行比较,结果是一个布尔值:
// GET: People
public ActionResult Index()
{
var propertyName = "Description";
var compareString = "abc";
var parameter = Expression.Parameter(typeof(Person));
var memberAccess = Expression.MakeMemberAccess(parameter, typeof(Person).GetProperty(propertyName));
var compare = Expression.Constant(compareString);
var contains = Expression.Call(memberAccess, typeof(string).GetMethod(nameof(string.Contains), new[] { typeof(string) }), compare);
var expr = Expression.Lambda<Func<Person, bool>>(contains, new[] { parameter });
return View(db.People.Where(expr).ToList());
}
//获取:人
公共行动结果索引()
{
var propertyName=“Description”;
var compareString=“abc”;
var参数=表达式参数(typeof(Person));
var memberAccess=Expression.MakeMemberAccess(参数,typeof(Person).GetProperty(propertyName));
var compare=表达式常数(compareString);
var contains=Expression.Call(memberAccess,typeof(string).GetMethod(nameof(string.contains),new[]{typeof(string)}),compare);
var expr=Expression.Lambda(contains,new[]{parameter});
返回视图(db.People.Where(expr.ToList());
}
当然,这会丢失所有检查、可能的选项、缓存等等。。。关键是,如果必须依赖运行时已知的类型,则必须自己创建表达式