有没有一种方法可以使用表达式从SQLite.net查询的模型中获取数据?

时间:2019-08-20 09:06:00

标签: c# reflection sqlite.net

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

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

我尝试了多种代码格式,包括表达式和Func设置的组合,将模型与SQLite查询分离并在其自身的表达式中获取ID,但是我相信,无论如何,所有内容都将一起编译。

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

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,因为这对于将来的开发人员来说很难阅读,而且容易出错。

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

0 个答案:

没有答案