我的代码使用linq语句获取查询,使其成为DbQuery
而不是ObjectQuery
,我使用该查询通过foreach循环添加参数。但DbQuery
没有参数支持。我知道我可以手动添加它们。但我的SQL语句中有36个不同的参数。所以我需要找到一种方法来添加参数。
foreach (var parameter in query.Parameters)
{
parameters.Add(new System.Data.SqlClient.SqlParameter { ParameterName = parameter.Name, Value = parameter.Value });
}
entities.Database.ExecuteSqlCommand(sql, parameters.ToArray());
这是我用于参数的代码。
我需要一种方法来DbQuery
答案 0 :(得分:1)
您可以通过附加表达式来撰写DbQuery
。通常用来做的一种模式是:
IQueryable<MyType> query = dbContext.Set<MyType>();
if (param1 != null)
query = query.Where(x => x.Property1 == param1);
if (param2 != null)
query = query.Where(x => x.Property2 == param2);
我不知道这是否适用于您的情况。如果不是,您可以随时诉诸ObjectQuery
。 DbContext
是ObjectContext
的包装,您可以通过((IObjectContextAdapter)dbContext).ObjectContext
得到后者。这是创建ObjectQueries的起点。
答案 1 :(得分:1)
我创建了一个扩展方法来获取参数
public static class ExpressionExtension
{
public static object[] GetParameters(this Expression expr)
{
var fetcher = new ParameterFetcher();
fetcher.Visit(expr);
return fetcher.Parameters.ToArray();
}
class ParameterFetcher : System.Linq.Expressions.ExpressionVisitor
{
public readonly List<object> Parameters = new List<object>();
protected Stack<string> CallingStringMethod = new Stack<string>();
protected int Visited = 0;
protected override Expression VisitMember(MemberExpression node)
{
if (Visited > 0)
{
Visited--;
}
else
{
var member = node;
while (member != null && member.Expression is MemberExpression)
{
member = (MemberExpression)member.Expression;
Visited++;
}
if (member != null && member.Expression.NodeType == ExpressionType.Constant)
{
var baseType = Nullable.GetUnderlyingType(node.Type) ?? node.Type;
if (baseType == typeof(string) || baseType == typeof(Guid) || baseType.IsPrimitive == true)
{
var objectMember = Expression.Convert(node, typeof(object));
var getterLambda = Expression.Lambda<Func<object>>(objectMember);
var value = getterLambda.Invoke();
if (value != null && CallingStringMethod.Count > 0)
{
switch (CallingStringMethod.Peek())
{
case "StartsWith":
value = Convert.ToString(value).Replace("[", "[[]").Replace("_", "[_]").Replace("%", "[%]") + "%";
break;
case "Contains":
value = "%" + Convert.ToString(value).Replace("[", "[[]").Replace("_", "[_]").Replace("%", "[%]") + "%";
break;
case "EndsWith":
value = "%" + Convert.ToString(value).Replace("[", "[[]").Replace("_", "[_]").Replace("%", "[%]");
break;
}
}
Parameters.Add(value);
}
}
}
return base.VisitMember(node);
}
protected override Expression VisitMethodCall(MethodCallExpression node)
{
if (node != null && node.Method.DeclaringType == typeof(string))
{
switch (node.Method.Name)
{
case "StartsWith":
case "Contains":
case "EndsWith":
CallingStringMethod.Push(node.Method.Name);
var val = base.VisitMethodCall(node);
CallingStringMethod.Pop();
return val;
}
}
return base.VisitMethodCall(node);
}
protected override Expression VisitParameter(ParameterExpression node)
{
return base.VisitParameter(node);
}
}
}
使用
....(IQueryable<TEntity> query)
var parameters = query.Expression.GetParameters();