6

我正在使用 Sqlite-Net ORM 并希望从表中删除与特定条件匹配的所有行,例如:

conn.Table<MyEntity>().Delete(t => t.someProperty == someValue);

有一些删除方法可以使用实体或主键。我现在当然可以获取所有符合我的条件的实体,然后分别为每个实体调用删除,但这感觉不对。

目前我正在使用

conn.Execute("DELETE FROM MyEntitiy...")

但是我不喜欢这个版本。如果我重命名我的类,硬编码的 SQL 将不再起作用。

我还有其他选择吗?

4

2 回答 2

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 类的可预测性如何,我认为这就是您目前被迫手动执行删除和更新的原因。所以测试和使用需要您自担风险:)

于 2014-02-26T22:53:10.550 回答
0

如果您只是想避免在类名中进行硬编码,您可以使用conn.Execute("DELETE FROM " + typeof(T).Name + "...").

于 2017-01-23T15:10:56.993 回答