首页 > 解决方案 > 有没有办法使用表达式从 SQLite.net 查询的模型中获取数据?

问题描述

我正在将作为模型接收的大量数据保存到 SQLite.net 数据库中的各种表中。我目前对每种数据库类型有 15 种方法,它们都采用相同的格式。我正在尝试使用反射编写一个方法,该方法允许我传入表达式,这些表达式从模型和数据库对象(dbo)中检索数据,它编译得很好,但模型数据无法编译为 SQL。

我收到的异常是“无法编译:参数”。

我已经尝试过此代码的各种格式,包括表达式和 Func 设置的组合,将模型与 SQLite 查询分开,并在其自己的表达式中获取之前的 ID,但是我相信无论如何,一切都在编译在一起。

这是为每种模型类型调用的 15 种方法中的一种的示例。我想用一种可以为我保存所有类型的方法替换它

private async Task SaveDevelopments(List<DevelopmentsModel> developmentModels)
{
    var toInsert = new List<DevelopmentsDBO>();
    var toUpdate = new List<DevelopmentsDBO>();

    foreach (var developmentModel in developmentModels)
    {
        var developmentDBO = await DatabaseHelpers.Table<DevelopmentsDBO>().Where(d => d.DevelopmentID == developmentModel.DevelopmentID).FirstOrDefaultAsync();
        if (developmentDBO == null)
        {
            developmentDBO = new DevelopmentsDBO();
            ModelFactory.UpdateFromModel(developmentDBO, developmentModel);
            toInsert.Add(developmentDBO);
        }
        else
        {
            ModelFactory.UpdateFromModel(developmentDBO, developmentModel);
            toUpdate.Add(developmentDBO);
        }
    }

    await DatabaseHelpers.InsertAllAsync(toInsert);
    await DatabaseHelpers.UpdateAllAsync(toUpdate);
}

这是尝试 1 使用反射和表达式将所有 15 种方法替换为共享方法

await SaveModels<DevelopmentDBO, DevelopmentsModel>(data.DevelopmentModels, (dbo, model) => dbo.DevelopmentID == model.DevelopmentID);

private async Task SaveModels<DBO, Model>(List<Model> models, Func<Model, DBO, bool> findSelf) where DBO : new()
{
    var toInsert = new List<DBO>();
    var toUpdate = new List<DBO>();

    foreach (var model in models)
    {
        var dbo = await DatabaseHelpers.Table<DBO>().Where(x => findSelf.Invoke(x, model)).FirstOrDefaultAsync();
        if (dbo == null)
        {
            dbo = (DBO)Activator.CreateInstance(typeof(DBO));
            ModelFactory.UpdateFromModel(dbo, model);
            toInsert.Add(dbo);
        }
        else
        {
            ModelFactory.UpdateFromModel(dbo, model);
            toUpdate.Add(dbo);
        }
    }

    await DatabaseHelpers.InsertAllAsync(toInsert);
    await DatabaseHelpers.UpdateAllAsync(toUpdate);
}

这是尝试 2

await SaveModels<DevelopmentDBO, DevelopmentsModel>(data.DevelopmentModels, x => x.DevelopmentID, x => x.DevelopmentID);

private async Task SaveModels<DBO, Model>(List<Model> models, Func<Model, Guid> findModelID, Expression<Func<DBO, Guid>> findDBOID) where DBO : new()
{
    var toInsert = new List<DBO>();
    var toUpdate = new List<DBO>();

    foreach (var model in models)
    {
        Guid modelID = findModelID.Invoke(model);

        Expression<Func<DBO, bool>> findSelf = x => findDBOID.Compile().Invoke(x) == modelID;

        var dbo = await DatabaseHelpers.Table<DBO>().Where(findSelf).FirstOrDefaultAsync();
        if (dbo == null)
        {
            dbo = (DBO)Activator.CreateInstance(typeof(DBO));
            ModelFactory.UpdateFromModel(dbo, model);
            toInsert.Add(dbo);
        }
        else
        {
            ModelFactory.UpdateFromModel(dbo, model);
            toUpdate.Add(dbo);
        }
    }

    await DatabaseHelpers.InsertAllAsync(toInsert);
    await DatabaseHelpers.UpdateAllAsync(toUpdate);
}

如上所述,我的目标是创建一种方法,可以用来替换 15 种几乎相同的方法来保存每种类型的 DBO。我不热衷于使用字符串格式的 SQL,因为这对于未来的开发人员来说很难阅读并且容易出错。

还有另一种我不知道的方法吗?

标签: c#reflectionsqlite.net

解决方案


推荐阅读