我正在使用Sqlite-Net ORM,并希望从表中删除符合特定条件的所有行,例如:
conn.Table<MyEntity>().Delete(t => t.someProperty == someValue);
有一些删除方法可以使用实体或主键。 我现在当然可以获得符合我条件的所有实体,然后单独为每个实体调用delete,但感觉不对。
目前我正在使用
conn.Execute("DELETE FROM MyEntitiy...")
但我不喜欢这个版本。如果我重命名我的类,硬编码的SQL将不再起作用。
我错过了其他选项吗?
答案 0 :(得分:5)
我查看了源代码,但没有看到任何可以使用谓词删除的地方。但是,以下扩展方法应提供您正在寻找的功能:
using System.Linq.Expressions;
using SQLite;
using System.Collections.Generic;
public static class DeleteExtensions
{
public static int Delete<T>(this TableQuery<T> tableQuery, Expression<Func<T, bool>> predExpr)
{
BindingFlags flags = BindingFlags.Instance | BindingFlags.NonPublic;
Type type = tableQuery.GetType();
MethodInfo method = type.GetMethod("CompileExpr", flags);
if (predExpr.NodeType == ExpressionType.Lambda) {
var lambda = (LambdaExpression)predExpr;
var pred = lambda.Body;
var args = new List<object> ();
var w = method.Invoke(tableQuery, new object[] {pred, args});
var compileResultType = w.GetType();
var prop = compileResultType.GetProperty("CommandText");
string commandText = prop.GetValue(w, null).ToString();
var cmdText = "delete from \"" + tableQuery.Table.TableName + "\"";
cmdText += " where " + commandText;
var command = tableQuery.Connection.CreateCommand (cmdText, args.ToArray ());
int result = command.ExecuteNonQuery();
return result;
} else {
throw new NotSupportedException ("Must be a predicate");
}
}
}
但是,我不确定使用TableQuery类是多么可预测,我认为这就是为什么你当前被迫手动删除和更新的原因。因此,测试和使用风险自负:)
答案 1 :(得分:0)
如果您只是想避免在班级名称中进行硬编码,可以使用conn.Execute("DELETE FROM " + typeof(T).Name + "...")
。