Ich glaube, ich habe derzeit einen Fehler in Entity Framework 6 und möglicherweise in ADO.NET. Da es eine Frist gibt, bin ich mir nicht sicher, ob ich warten kann, bis dieser Fehler behoben ist, und hoffentlich kann mir jemand bei einer sauberen Lösung helfen.
Das Problem ist, dass die Abfrage die Werte 1 und 5 an Stellen verwendet, an denen sie 0,01 und 0,05 betragen sollte. Allerdings scheint seltsamerweise 0.1 zu funktionieren
Die generierte Abfrage lautet derzeit: (vom SQL Server Profiler abgerufen)
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
Während der richtige Code wäre:
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
Ich habe hier bereits ein Problem mit github erstellt: Benutzerdefinierte Tabelle, die einen falschen Wert einfügt
Ich möchte eine benutzerdefinierte Tabelle in meiner parametrisierten Abfrage verwenden. In dieser Frage wird erläutert, wie dies getan wird: Wertparameter der Tabelle für gespeicherte Prozedurentitäten in Entity Framework
Dies ist der C # -Code, der zum Abrufen des obigen SQL-Codes verwendet wird
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());
Und SQL-Code, um die benutzerdefinierte Tabelle zu erhalten
CREATE TYPE [dbo].[someUDT] AS TABLE
(
[value1] [decimal](16, 5) NULL,
[value2] [decimal](16, 5) NULL
)
EDIT:
Gert Arnold hat es herausgefunden. Basierend auf seiner Antwort habe ich hier einen vorhandenen Bericht gefunden. Die SQL Server Profiler TextData-Spalte behandelt Dezimaleingaben falsch
dataTable.Rows.Add(null,0.05m);
Select * from @AName
als Platzhalter ist. Ich nehme tatsächlich an einer größeren Abfrage teil, die meiner Meinung nach für die Frage nicht relevant war, da dies das Problem bereits in einem einfacheren Format repliziert.Database.SqlQuery
(anstattDatabase.ExecuteSqlCommand
) verwende, erhalte ich die richtigen Werte im Client!Antworten:
Es ist ein seltsames SQL Profiler-Artefakt. Die Werte werden korrekt übertragen. Ich kann das demonstrieren, indem ich eine Datenbank mit Ihrem benutzerdefinierten Typ und einer kleinen Tabelle erstelle:
Und ein paar Werte einfügen:
Dann führe ich Ihren Code aus, leicht angepasst:
(
MyContex
ist nur eine Klasse, die vonDbContext
und sonst nichts erbt )Es gibt nur einen Wert zwischen
0.001m
und0.03m
und genau das gibt die Abfrage zurück :4
.Der SQL Server-Profiler protokolliert jedoch Folgendes:
Und in SSMS gibt das Datensatz Nr. 2 zurück.
Ich denke, es hat mit regionalen Einstellungen und Dezimaltrennzeichen zu tun, die irgendwo in der Protokollierung mit Dezimalgruppentrennzeichen verwechselt werden.
quelle
Ehrlich gesagt habe ich nicht das gleiche Problem wie Sie:
Dies ist mein Profiler-Protokoll:
Ich habe EntityFramework Version 6.2.0 & 6.3.0 & 6.4.0 ausprobiert und keines davon zeigt das Problem:
Außerdem teste ich ADO.NET und habe das gleiche Ergebnis:
Ich verwende Visual Studio 2017, .NET Framework 4.6.1 und Microsoft SQL Server Enterprise (64-Bit).
quelle