查找和分析在具有一个参数

问题描述:

LINQ表达式的方法where子句我有以下方法:查找和分析在具有一个参数

public AgentContact GetAgentContacts(Expression<Func<AgentContact, bool>> predicate) 
{ 
    return _db.AgentContacts.Where(predicate).First(); 
} 

那我用下面的呼吁:

var agentcontacts = _rep.GetAgentContacts(agent => agent.AGENTID == id); 

我从来没有研究解析出表达式树。我需要做的是验证是否使用了必需的Entity框架的域模型数据库表列名称。在这种情况下是“AGENTID”。为了扩大这一点,我需要的例子能够为大量的数据库列名的解析在该呼叫的lambda表达式:

var busAddress = _rep.GetBusAddresses(ba=>ba.BUSID==id && ba.ADDRESS_TYPE == addressTyp); 
if (busAddress.Any()) 
{ 
    return View(busAddress.First()); 
} 

将寻找“BUSID”和“ADDRESS_TYPE”。所有这一切都是为了找出表达式是否正在使用查询表的主键。在使用主键时,我有要求使用现有的存储过程。

任何对资源的帮助或指导都会有帮助。

==============其他要求====================== 作为对此的后续问题,我将如何编码以确保表达式仅包含实体的公共属性?

+0

这是不相关的问题,但'Enumerable.First'也需要一个谓词,所以你可以用_db.AgentContacts.First(谓词)替换'_db.AgentContacts.Where(predicate).First();' –

如果我理解正确,你有一个Expression,你想知道是否在该表达式中访问了一个特定的属性。要发现这一点,您可以使用ExpressionVisitor:覆盖其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