Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/linq/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
.net 在具有参数LINQ表达式的方法中查找和分析where子句_.net_Linq_Expression Trees - Fatal编程技术网

.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>