代码之家  ›  专栏  ›  技术社区  ›  BVernon

EF错误的解决方法?

  •  0
  • BVernon  · 技术社区  · 3 年前

    我前几天注意到了这个错误,今天再次确认了它。还发现其他人有这个问题。

    实体框架将不返回任何结果(当它应该返回时),并且在以下场景中不会抛出异常:

    • 使用SqlQuery方法执行存储过程
    • 至少提供一个可选参数
    • 至少跳过一个可选参数

    我所说的“跳过”是指进程签名中参数的顺序。只要你不跳过任何可选参数,就没有问题;只有当您提供了一个可选参数,该参数位于另一个未包含的参数之后。

    可能还有其他变体。例如,我怀疑如果您在跳过的可选参数之后提供了一个必需的参数,也会出现同样的问题。。。但对此并不确定。

    现在考虑这个场景:

    我在进程签名的末尾添加了一个新的可选参数。现在我更新了一个SqlQuery()调用并添加了新的参数,但由于前面提到的错误,我没有得到任何结果。我有两个选择:1)我可以添加我遗漏的所有可选参数。或者2)我可以将新参数移到签名中的左边,这样我就不再跳过SqlQuery()调用中的任何参数。

    当然,2)的问题在于,这可能会破坏正在跳过该参数的现有代码。所以,实际上,我唯一的选择似乎是一直包括所有参数,这完全违背了最初拥有可选参数的全部目的。

    有什么方法可以解决这个问题吗?或者如果我使用实体框架调用存储的proc,我只是不得不始终传入所有参数吗?

    编辑:我看到的另一个潜在问题是,它不允许我让SQL使用默认值,因为没有可以传递给SQL的“值”来告诉它使用默认值。你告诉它通过不传递值来使用默认值。。。EF似乎没有正确处理。

    编辑2:

    最小可复制代码:

    CREATE PROC MyProc @p1 int, @p2 int = 0, @p3 int = 0
    as
    select * from MyTable 
    where  p1 = @p1 
           and (@p2 = 0 or p2 = @p2)
           and (@p3 = 0 or p3 = @p3)
    

    C#代码:

    List<MyObject> SomeMethod(int p1, int p3)
    {
        return db.Database.SqlQuery<MyObject>("dbo.MyProc @p1, @p3",
             new SqlParameter("@p1", p1),
             new SqlParameter("@p3", p3)
         ).ToList();
    }
    
    0 回复  |  直到 3 年前