gpt4 book ai didi

c# - Entity Framework 中的用户定义表生成不正确的查询

转载 作者:行者123 更新时间:2023-12-02 03:26:28 25 4
gpt4 key购买 nike

我认为我当前在 Entity Framework 6 中遇到错误,也可能在 ADO.NET 中遇到错误。由于有截止日期,我不确定我是否可以等待此错误得到修复,希望有人可以帮助我解决问题。

问题是查询在应该为 0.01 和 0.05 的地方使用了值 1 和 5。然而奇怪的是 0.1 似乎有效

当前生成的查询是:(从 SQL Server Profiler 获取)

declare @p3  dbo.someUDT
insert into @p3 values(NULL,5)
insert into @p3 values(5,0.10)
insert into @p3 values(NULL,1)
insert into @p3 values(1,2)

exec sp_executesql N'Select * from @AName',N'@AName [dbo].[someUDT] READONLY',@AName=@p3

正确的代码是:

declare @p3  dbo.someUDT
insert into @p3 values(NULL,0.05)
insert into @p3 values(0.05,0.10)
insert into @p3 values(NULL,0.01)
insert into @p3 values(0.01,0.02)

exec sp_executesql N'Select * from @AName',N'@AName [dbo].[someUDT] READONLY',@AName=@p3

我已经在 github 上创建了一个问题:User defined table inserting wrong value

我想在参数化查询中使用用户定义的表,这个问题解释了这是如何完成的: Entity Framework Stored Procedure Table Value Parameter

这是用于获取上面 SQL 代码的 C# 代码

DataTable dataTable = new DataTable();
dataTable.Columns.Add("value1", typeof(decimal));
dataTable.Columns.Add("value2", typeof(decimal));

dataTable.Rows.Add(null,0.05m);
dataTable.Rows.Add(0.05m,0.1m);
dataTable.Rows.Add(null,0.01m);
dataTable.Rows.Add(0.01m,0.02m);
List<SqlParameter> Parameters = new List<SqlParameter>();

Parameters.Add(new SqlParameter("@AName", SqlDbType.Structured) { Value = dataTable , TypeName= "dbo.someUDT" });

dbContext.Database.ExecuteSqlCommand("Select * from @AName", Parameters.ToArray());

以及获取用户定义表的SQL代码

CREATE TYPE [dbo].[someUDT] AS TABLE
(
[value1] [decimal](16, 5) NULL,
[value2] [decimal](16, 5) NULL
)

编辑:
Gert Arnold弄清楚了。根据他的回答,我在这里找到了一份现有报告SQL Server Profiler TextData Column handles Decimal Inputs Incorrectly

最佳答案

这是一个奇怪的 Sql Profiler 工件。值传输正确。我可以通过使用用户定义的类型和一个小表创建一个数据库来演示这一点:

CREATE TABLE [dbo].[Values](
[Id] [int] IDENTITY(1,1) NOT NULL,
[Value] [decimal](16, 5) NOT NULL,
CONSTRAINT [PK_Values] PRIMARY KEY CLUSTERED ([Id] ASC) ON [PRIMARY]
GO

并插入几个值:

Id          Value
----------- ---------------------------------------
1 10.00000
2 1.00000
3 0.10000
4 0.01000

然后我运行你的代码,稍作修改:

DataTable dataTable = new DataTable();
dataTable.Columns.Add("value1", typeof(decimal));
dataTable.Columns.Add("value2", typeof(decimal));

dataTable.Rows.Add(0.001m, 0.03m);
List<SqlParameter> Parameters = new List<SqlParameter>();

Parameters.Add(new SqlParameter("@AName", SqlDbType.Structured) { Value = dataTable, TypeName = "dbo.someUDT" });

using(var context = new MyContext(connStr))
{
var query = "Select v.Id from dbo.[Values] v, @AName a "
+ " where v.Value BETWEEN a.value1 AND a.value2";
var result = context.Database.SqlQuery<int>(query, Parameters.ToArray());
}

(MyContex 只是一个继承自 DbContext 的类,仅此而已)

0.001m0.03m 之间只有一个值 这正是查询返回的值:4.

但是,Sql Server Profiler 会记录以下内容:

declare @p3 dbo.someUDT
insert into @p3 values(1,3) -- See here: the log is warped

exec sp_executesql N'Select v.Value from dbo.[Values] v, @AName a where v.Value BETWEEN a.value1 AND a.value2',N'@AName [dbo].[someUDT] READONLY',@AName=@p3

在 SSMS 中返回记录 #2。

我认为这与区域设置和小数分隔符与日志记录中某处的小数组分隔符混合有关。

关于c# - Entity Framework 中的用户定义表生成不正确的查询,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59152654/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com