【问题标题】:Entity Framework Core Linq query returning ids which do not exist in databaseEntity Framework Core Linq 查询返回数据库中不存在的 id
【发布时间】:2018-08-31 23:10:56
【问题描述】:

我想知道是否有一种简单的方法使用 Linq to SQL 和 Entity Framework Core 来查询数据库中是否存在给定的 id 列表并返回不存在的 id 列表。

我遇到的用例是,如果用户可以使用对象列表(通过他们的 id 列表表示)做某事,我想检查这些 id 是否存在。

当然,我可以查询数据库中存在的所有对象/对象 ID,然后在第二步中进行交叉检查。

只是想知道是否可以一步到位。

我在代码中的意思:

public class MyDbObject 
{
    public int Id { get; set; }
    public string Name { get; set; }
}

public IActionResult DoSomethingWithObjects([FromQuery]List<int> ids} 
{
    List<int> idsThatDoNotExistInTheDb = DbContext.MyDbObject.Where(???)

    return NotFound("those ids do not exist: " + string.Join(", ", idsThatDoNotExist));
}

【问题讨论】:

    标签: c# linq linq-to-sql .net-core entity-framework-core


    【解决方案1】:

    您可以获取匹配的 ID 列表,然后将它们从原始列表中删除,如下所示:

    var validIds = DbContext
        .MyDbObject
        .Where(obj => ids.Contains(obj.Id))
        .Select(obj => obj.Id);
    var idsThatDoNotExistInTheDb = ids.Except(validIds);
    

    不过,这种方法可能会很慢,因此最好在采用表值参数的存储过程中执行此方法 (how?)

    注意:此类预检查并非万无一失,因为在您验证 ID 和开始操作之间可能会发生变化。最好以一种可以验证的方式构建您的 API,然后立即执行它需要执行的任何操作。如果验证失败,API 会返回一个错误列表。

    【讨论】:

    • 一个问题到你的笔记。任何提示我如何重组它?假设用例是我想在 MyDbObject 和 MyDbObject2 之间的 m:n 表中使用 MyDbObject 的 ID,并且我想避免等待 DbUpdateException。由于缺少其中一个 id 而无法设置其中一个外键(在 m:n 表中)会引发这种情况。所以我做这个预检查并返回一个错误或一个 InternalServerError 如果它在两者之间被删除。还没想出如何“完美”解决这个问题。
    • 重组不一定使用linq。
    • @monty 捕获DbUpdateException 本身并没有错,只是它不会为您提供未通过验证的 ID 列表。解决此问题的一种方法是创建一个存储过程,该过程执行验证并在单个事务中执行您希望执行的操作。此存储过程将返回失败 ID 的列表,如果一切正常,则返回一个空列表。
    • 效果很好。谢谢
    猜你喜欢
    • 2017-03-19
    • 2019-12-02
    • 1970-01-01
    • 1970-01-01
    • 2016-05-19
    • 2011-03-13
    • 1970-01-01
    • 2016-02-27
    • 1970-01-01
    相关资源
    最近更新 更多