c# – Entity Framework似乎用它们的实际值替换参数

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

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))

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

WHERE ([Extent4].[AreaLevel] = 2) AND ([Extent1].[DimensionId] = [Extent4].[AreaId]) AND ([Extent5].[GroupId] = @106929) AND ([Extent5].[IsActive] = 1) AND ([Extent5].[AreaId] = [Extent1].[DimensionId])

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

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

我的问题:

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

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

最佳答案 这确实很奇怪.即使您可能不想更改上下文,临时添加一些自定义日志记录是否合理?今天早些时候我碰巧在 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__’”,但我会把它留给你!

点赞