我想使用LINQ表达式作为方法参数来构建Dapper字符串。我在MS Docs找到了一个解析示例并将其集成到我的代码中:
public static List<Notification> GetNotifs(Expression<Func<Notification, bool>> p)
{
using (var connection = new SqlConnection(ConfigurationManager.ConnectionStrings["DefaultConnection"].ConnectionString))
{
string sqlQ = "SELECT * FROM Notifications WHERE ";
ParameterExpression param = p.Parameters[0];
BinaryExpression operation = (BinaryExpression)p.Body;
ParameterExpression left = (ParameterExpression)operation.Left;
for (int i = 0; i < left.Name.Length; i++) { if (i <= param.Name.Length) { } else { sqlQ += left.Name[i]; } }
ConstantExpression right = (ConstantExpression)operation.Right;
if (operation.NodeType.ToString() == "LessThan") sqlQ += " <";
else if (operation.NodeType.ToString() == "GreaterThan") sqlQ += " >";
else if (operation.NodeType.ToString() == "LessThanOrEqual") sqlQ += " <=";
else if (operation.NodeType.ToString() == "GreaterThanOrEqual") sqlQ += " >=";
else if (operation.NodeType.ToString() == "Equal") sqlQ += " =";
else if (operation.NodeType.ToString() == "NotEqual") sqlQ += " !=";
sqlQ += " " + right.Value;
return connection.Query<Notification>(sqlQ).ToList();
}
}
但是,不幸的是,它在
处给出了InvalidCastExceptionParameterExpression left = (ParameterExpression)operation.Left;
此方法的调用类似于:
DRepository.GetNotifs(uid => uid.U_Id == id)
您能帮我找出我在哪里不正确吗?
答案 0 :(得分:1)
下面的示例生成SQL SELECT * FROM Notifications WHERE U_Id = 1
:
[Test]
public void DapperExpression()
{
// Arrange
var id = 1;
// Act
var list = GetNotifs(uid => uid.U_Id == id);
// Assert
Assert.IsNotEmpty(list);
}
public static List<Notification> GetNotifs(Expression<Func<Notification, bool>> p)
{
using (var connection = new SqlConnection(ConfigurationManager.ConnectionStrings["DefaultConnection"].ConnectionString))
{
string sqlQ = "SELECT * FROM Notifications WHERE ";
ParameterExpression param = p.Parameters[0];
BinaryExpression operation = (BinaryExpression)p.Body;
var t = operation.Left.GetType();
MemberExpression left = (MemberExpression)operation.Left;
sqlQ += left.Member.Name;
MemberExpression right = (MemberExpression)operation.Right;
ConstantExpression cnst = (ConstantExpression) right.Expression;
var field = cnst.Type.GetFields().Single();
var val = field.GetValue(cnst.Value);
if (operation.NodeType.ToString() == "LessThan") sqlQ += " <";
else if (operation.NodeType.ToString() == "GreaterThan") sqlQ += " >";
else if (operation.NodeType.ToString() == "LessThanOrEqual") sqlQ += " <=";
else if (operation.NodeType.ToString() == "GreaterThanOrEqual") sqlQ += " >=";
else if (operation.NodeType.ToString() == "Equal") sqlQ += " =";
else if (operation.NodeType.ToString() == "NotEqual") sqlQ += " !=";
sqlQ += " " + val;
return connection.Query<Notification>(sqlQ).ToList();
}
}
请注意,在int
的情况下它将起作用。例如,您应该添加一些与类型有关的逻辑以为string
或Guid
添加仲裁。您可以从field
变量中获取此类型。希望对您有所帮助。