0

I have the following method:

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

That I call with the following:

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

I have never looked into parsing out the expression tree. What I need to do is verify that has the required Entity framework's domain model database table column names have been used. Which in this case is "AGENTID". To extend this, I need the example to be able to parse for a number of database column names as in the lambda expression for this call:

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

which will look for "BUSID" and "ADDRESS_TYPE". All this is to find out if the expression is using the primary key for the table being queried. I have a requirement to use existing stored procedures when using the primary key.

Any help or direction to resources would truly be helpful.

============== Additional requirement ====================== As a follow on to this question, how would I code to make sure that the expression contains only the public properties of the Entity?

4

1 回答 1

0

如果我对您的理解正确,您有一个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
于 2013-05-25T19:35:07.923 回答