查找和分析在具有一个参数
问题描述:
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”。所有这一切都是为了找出表达式是否正在使用查询表的主键。在使用主键时,我有要求使用现有的存储过程。
任何对资源的帮助或指导都会有帮助。
==============其他要求====================== 作为对此的后续问题,我将如何编码以确保表达式仅包含实体的公共属性?
答
如果我理解正确,你有一个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
这是不相关的问题,但'Enumerable.First'也需要一个谓词,所以你可以用_db.AgentContacts.First(谓词)替换'_db.AgentContacts.Where(predicate).First();' –