Closed iJungleboy closed 7 years ago
Note for triage: this looks like another manifestation of #6835
/cc @divega @AndriySvyryd
@iJungleboy What is the actual column type for Value?
@iJungleboy Also, does the index IX_EAV_Values2 containing the column actually exist in the database, or is it only defined in EF?
@AndriySvyryd Try using nvarchar(max) for all TVV columns in SQL Server 2008
@ajcvickers The real type is nvarchar(max), and no, it was not in the DB index at all, that must be a minor bug in the DB-First model generation.
@AndriySvyryd As noted the column is already nvarchar(max) and the SQL version is 2012
@iJungleboy Would it be possible to get a repro that caused this index to get reverse engineered? Hopefully, if you can post the table definitions we can do it from there.
No problem - it's part of an open source EAV solution https://github.com/2sic/eav-server for the .net CMS DNN.
Here's the table definition, I assume it's complete but tell me if I missed something.
GO
/****** Object: Table [dbo].[ToSIC_EAV_Values] Script Date: 02.05.2017 13:00:28 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[ToSIC_EAV_Values](
[ValueID] [int] IDENTITY(1,1) NOT NULL,
[EntityID] [int] NOT NULL,
[AttributeID] [int] NOT NULL,
[Value] [nvarchar](max) NOT NULL,
[ChangeLogCreated] [int] NOT NULL,
[ChangeLogDeleted] [int] NULL,
[ChangeLogModified] [int] NULL,
CONSTRAINT [PK_ToSIC_EAV_Values] PRIMARY KEY CLUSTERED
(
[ValueID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
GO
ALTER TABLE [dbo].[ToSIC_EAV_Values] WITH CHECK ADD CONSTRAINT [FK_ToSIC_EAV_Values_ToSIC_EAV_Attributes] FOREIGN KEY([AttributeID])
REFERENCES [dbo].[ToSIC_EAV_Attributes] ([AttributeID])
ON DELETE CASCADE
GO
ALTER TABLE [dbo].[ToSIC_EAV_Values] CHECK CONSTRAINT [FK_ToSIC_EAV_Values_ToSIC_EAV_Attributes]
GO
ALTER TABLE [dbo].[ToSIC_EAV_Values] WITH CHECK ADD CONSTRAINT [FK_ToSIC_EAV_Values_ToSIC_EAV_ChangeLogCreated] FOREIGN KEY([ChangeLogCreated])
REFERENCES [dbo].[ToSIC_EAV_ChangeLog] ([ChangeID])
GO
ALTER TABLE [dbo].[ToSIC_EAV_Values] CHECK CONSTRAINT [FK_ToSIC_EAV_Values_ToSIC_EAV_ChangeLogCreated]
GO
ALTER TABLE [dbo].[ToSIC_EAV_Values] WITH CHECK ADD CONSTRAINT [FK_ToSIC_EAV_Values_ToSIC_EAV_ChangeLogDeleted] FOREIGN KEY([ChangeLogDeleted])
REFERENCES [dbo].[ToSIC_EAV_ChangeLog] ([ChangeID])
GO
ALTER TABLE [dbo].[ToSIC_EAV_Values] CHECK CONSTRAINT [FK_ToSIC_EAV_Values_ToSIC_EAV_ChangeLogDeleted]
GO
ALTER TABLE [dbo].[ToSIC_EAV_Values] WITH CHECK ADD CONSTRAINT [FK_ToSIC_EAV_Values_ToSIC_EAV_ChangeLogModified] FOREIGN KEY([ChangeLogModified])
REFERENCES [dbo].[ToSIC_EAV_ChangeLog] ([ChangeID])
GO
ALTER TABLE [dbo].[ToSIC_EAV_Values] CHECK CONSTRAINT [FK_ToSIC_EAV_Values_ToSIC_EAV_ChangeLogModified]
GO
ALTER TABLE [dbo].[ToSIC_EAV_Values] WITH CHECK ADD CONSTRAINT [FK_ToSIC_EAV_Values_ToSIC_EAV_Entities] FOREIGN KEY([EntityID])
REFERENCES [dbo].[ToSIC_EAV_Entities] ([EntityID])
GO
ALTER TABLE [dbo].[ToSIC_EAV_Values] CHECK CONSTRAINT [FK_ToSIC_EAV_Values_ToSIC_EAV_Entities]
GO
@iJungleboy Thanks very much for posting that so quickly. Hopefuly quick follow-up question: do you know if any other table references the "Value" column in, for example, a foreign key constraint?
I don't think so, but I've included the full SQL to create the tables and stored procedures which are in use. eav-db.sql.txt
Entity Framework Core auto-generates SQL-Statements to cause updates to happen. When a string-value is used as a key, it will by default use nvarchar(450) instead of nvarchar(max).
The problem is that this also happens in a few (but not all) code generated for string values which are in an index (instead of a key). Specifically, the temporary table which is used in the SQL for merge operations will incorrectly assume an nvarchar(450) and then fail when trying to place the initial nvarchar(max) value in this temp table.
The exception will then look be:
SqlException: String or binary data would be truncated.
The full exception shown is:The SQL which was sent to the SQL Server was the following:
As you can see, the
@p5
is correctly treated as annvarchar(max)
but the temporary table@toInsert0
creates a column[Value]
which is cast asnvarchar(450)
- triggering this problem.In my case I had a DB first model which simply imported the indexes into the OnModelCreating ModelBuilder on my DbContext resulting in this index being managed:
When I commented out the information that
e.Value
is part of the index, everything worked flawlessly:It's important to note that many changes to this data type were not affected/hurt by the index-information. Just some very specific ones caused this problem.
Steps to reproduce
My code is too complex to use when reproducing, sorry. But I hope the full explanation above clarifies everything.
Further technical details
EF Core version: 1.1.1 Database Provider: Microsoft.EntityFrameworkCore.SqlServer Operating system: Windows 10 Dev environment, Windows 2012 R2 Web Server, IIS IDE: Visual Studio 2017