实体框架似乎用它们的实际值替换参数

时间:2017-04-28 21:02:41

标签: c# .net entity-framework entity-framework-6

我们在日志中看到一大堆关于的错误必须声明标量变量" @" 或其他类似的东西。跟踪生成错误的实际SQL,它们似乎是实体框架生成的SQL语句。这是一个例子:

myfile.exe|out

造成错误的原因是@' Brunswick' line,应该是我们正在寻找的用户名。因此,它好像实体框架正在交换@ p0或具有实际值的东西。我们也看到很多关于@ 2892734等问题的错误,所以数字参数也会受到影响。例如:

SELECT TOP (1) 
    [Extent1].[AccountId] AS [AccountId], 
    [Extent1].[Username] AS [Username], 
    [Extent1].[EmployerId] AS [EmployerId], 
    [Extent1].[EmployeeId] AS [EmployeeId], 
    [Extent1].[SubscriberId] AS [SubscriberId], 
    [Extent1].[RelationshipCode] AS [RelationshipCode], 
    [Extent1].[AccountType] AS [AccountType], 
    [Extent1].[AccountStatus] AS [AccountStatus]
    FROM [dbo].[jc_Accounts] AS [Extent1]
    WHERE (@'Brunswick' = [Extent1].[Username]) OR ((@'Brunswick' IS NULL) AND ([Extent1].[Username] IS NULL))

不幸的是,我们的数据库上下文和实体存储库代码是您在最糟糕的噩梦中看到的。很多事情都没有被触及多年,包装器周围的包装器,使用反射将POCO映射到存储过程调用的东西,以及各种有趣的东西。我们花了很多时间在这上面,我们还没有找到任何可以解决这个问题的事情。

我们还将实体框架从4升级到5到6以及其他版本,这个错误仍然存​​在。所以我不认为这是一个奇怪的EF错误。

我的问题:

在什么情况下EF会产生这样的查询?或者,如果它确实是我们已经扩展实体框架的某种自定义事物,那么我想要开始研究哪种扩展?我正在寻找可以搜索代码库的东西,并获得一些线索。

我不需要一个完整的答案,我正在寻找EF专家的一些想法让我走上正轨。我可以添加更多详细信息,请在下面提问。

2 个答案:

答案 0 :(得分:1)

确实很奇怪。即使您可能不想更改上下文,临时添加一些自定义日志记录是否合理?今天早些时候,我碰巧在another post中给出了这个例子:

public MyContext : DbContext
{
    private static ILog log = LogManager.GetCurrentClassLogger();

    public MyContext(string connectionString)
        : base(connectionString)
    {
        this.Database.Log = (msg) => log.Trace(msg);
    }
}

然而,非常暂时,如果你可以重现查询,你可以做类似的事情,当它发生时打破然后爬上callstack:

public MyContext : DbContext
{
    private static ILog log = LogManager.GetCurrentClassLogger();

    public MyContext(string connectionString)
        : base(connectionString)
    {
        this.Database.Log = (msg) => 
        {
            if (msg.Contains("@'Brunswick'"))
                Debugger.Break();
        };
    }
}

如果你喜欢正则表达式,或者如果你不总是得到相同的变量替换,你可以使msg匹配“@后面没有'p__linq__'”,但我会留下给你!

答案 1 :(得分:1)

如果我没弄错的话,我已经看到了其中一些 并且是例如使用了的状况 Take(20)代替Take(()=>20)

或另一个案例是 var a = []{'a','b','c'} var res = context.Users.Where(u=>a.contains(u.Id))