.net 在具有参数LINQ表达式的方法中查找和分析where子句
我有以下方法:.net 在具有参数LINQ表达式的方法中查找和分析where子句,.net,linq,expression-trees,.net,Linq,Expression Trees,我有以下方法: public AgentContact GetAgentContacts(Expression<Func<AgentContact, bool>> predicate) { return _db.AgentContacts.Where(predicate).First(); } 我从未研究过解析表达式树。我需要做的是验证是否使用了所需实体框架的域模型数据库表列名。在本例中是“AGENTID”。为了扩展这一点,我需要该示例能够解析许多数据库列名,
public AgentContact GetAgentContacts(Expression<Func<AgentContact, bool>> predicate)
{
return _db.AgentContacts.Where(predicate).First();
}
我从未研究过解析表达式树。我需要做的是验证是否使用了所需实体框架的域模型数据库表列名。在本例中是“AGENTID”。为了扩展这一点,我需要该示例能够解析许多数据库列名,如此调用的lambda表达式中所示:
var busAddress = _rep.GetBusAddresses(ba=>ba.BUSID==id && ba.ADDRESS_TYPE == addressTyp);
if (busAddress.Any())
{
return View(busAddress.First());
}
它将查找“BUSID”和“ADDRESS\u TYPE”。所有这些都是为了确定表达式是否使用了被查询表的主键。在使用主键时,我需要使用现有的存储过程
任何对资源的帮助或指导都将真正有帮助
===================附加要求======================
作为这个问题的后续问题,我将如何编写代码以确保表达式只包含实体的公共属性?如果我理解正确,您有一个
表达式,并且您想知道是否在该表达式中访问了特定属性。要找到答案,可以使用:重写它的VisitMember()
,并在其中将表达式中的成员与要查找的成员进行比较
整个代码可以如下所示:
public class ExpressionPropertyFinder<T>
{
private readonly ExpressionPropertyFinderVisitor m_visitor;
private ExpressionPropertyFinder(MemberInfo member)
{
m_visitor = new ExpressionPropertyFinderVisitor(member);
}
// constructor can't be generic
public static ExpressionPropertyFinder<T> Create<TProperty>(
Expression<Func<T, TProperty>> propertyExpression)
{
return new ExpressionPropertyFinder<T>(
((MemberExpression)propertyExpression.Body).Member);
}
public bool IsMemberAccessed(Expression<Func<T, bool>> expression)
{
return m_visitor.IsMemberAccessed(expression);
}
}
class ExpressionPropertyFinderVisitor : ExpressionVisitor
{
private readonly MemberInfo m_member;
private bool m_found;
public ExpressionPropertyFinderVisitor(MemberInfo member)
{
m_member = member;
}
public bool IsMemberAccessed(Expression expression)
{
m_found = false;
Visit(expression);
return m_found;
}
protected override Expression VisitMember(MemberExpression node)
{
if (node.Member == m_member)
m_found = true;
return base.VisitMember(node);
}
}
var finder = ExpressionPropertyFinder<Entity>.Create(e => e.Id);
finder.IsMemberAccessed(e => e.Id == 42) // true
finder.IsMemberAccessed(e => e.Name == "foo") // false
finder.IsMemberAccessed(e => e.Id == 42 && e.Name == "foo") // true
公共类ExpressionPropertyFinder
{
私有只读ExpressionPropertyFinderVisitor m_visitor;
private ExpressionPropertyFinder(MemberInfo成员)
{
m_visitor=新ExpressionPropertyFindVisitor(会员);
}
//构造函数不能是泛型的
公共静态表达式PropertyFinder创建(
表达式属性(表达式)
{
返回新的ExpressionPropertyFinder(
((MemberExpression)propertyExpression.Body).Member);
}
公共布尔ISMemberAccess(表达式)
{
返回m_visitor.IsMemberAccessed(表达式);
}
}
类ExpressionPropertyFindVisitor:ExpressionVisitor
{
私有只读成员信息m_成员;
私人布尔穆发现;
public ExpressionPropertyFinderVisitor(MemberInfo成员)
{
m_成员=成员;
}
公共布尔ISMemberAccess(表达式)
{
m_found=假;
参观(表达);
返回找到的m_;
}
受保护的重写表达式VisitMember(MemberExpression节点)
{
if(node.Member==m_成员)
m_found=true;
返回base.VisitMember(节点);
}
}
然后您可以这样使用它:
public class ExpressionPropertyFinder<T>
{
private readonly ExpressionPropertyFinderVisitor m_visitor;
private ExpressionPropertyFinder(MemberInfo member)
{
m_visitor = new ExpressionPropertyFinderVisitor(member);
}
// constructor can't be generic
public static ExpressionPropertyFinder<T> Create<TProperty>(
Expression<Func<T, TProperty>> propertyExpression)
{
return new ExpressionPropertyFinder<T>(
((MemberExpression)propertyExpression.Body).Member);
}
public bool IsMemberAccessed(Expression<Func<T, bool>> expression)
{
return m_visitor.IsMemberAccessed(expression);
}
}
class ExpressionPropertyFinderVisitor : ExpressionVisitor
{
private readonly MemberInfo m_member;
private bool m_found;
public ExpressionPropertyFinderVisitor(MemberInfo member)
{
m_member = member;
}
public bool IsMemberAccessed(Expression expression)
{
m_found = false;
Visit(expression);
return m_found;
}
protected override Expression VisitMember(MemberExpression node)
{
if (node.Member == m_member)
m_found = true;
return base.VisitMember(node);
}
}
var finder = ExpressionPropertyFinder<Entity>.Create(e => e.Id);
finder.IsMemberAccessed(e => e.Id == 42) // true
finder.IsMemberAccessed(e => e.Name == "foo") // false
finder.IsMemberAccessed(e => e.Id == 42 && e.Name == "foo") // true
var finder=ExpressionPropertyFinder.Create(e=>e.Id);
finder.IsMemberAccessed(e=>e.Id==42)//true
finder.IsMemberAccessed(e=>e.Name==“foo”)//false
finder.IsMemberAccessed(e=>e.Id==42&&e.Name==“foo”)//true
这与问题无关,但可枚举。First
还接受谓词,因此您可以替换\u db.AgentContacts.Where(谓词).First()带有\u db.AgentContacts.First(谓词)的code>代码>