Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

EF Core 3.1 query generation with long being used as a string value generates cast to nvarchar(3) #20732

Closed
jons-aura opened this issue Apr 23, 2020 · 5 comments

Comments

@jons-aura
Copy link

I have a query that needs to do a join based on the string concatenation of a string column and a bigint column (yes it's disgusting but we inherited the schema and can't yet change it).

Steps to reproduce

When I use the Linq clause y.StringColumn+ "-" + y.NumberColumn) == x.tmr.OtherSideOfTheJoin the generated SQL looks like ((([w].[StringColumn] + N'-') + CAST([w].[NumberColumn] AS nvarchar(3))) = [m].[OtherSideOfTheJoin]) which fails for any value greater than 3 decimal digits.

If I use an explicit ToString() call y.StringColumn+ "-" + y.NumberColumn.ToString()) == x.tmr.OtherSideOfTheJoin the generated query looks like ((([w0].[WRBCOD] + N'-') + CONVERT(VARCHAR(20), [w0].[WRCUST])) = [m].[RAW_BC_CUSTNUM]) which succeeds.

Why in the world is EF generating nvarchar(3) for the implicit conversion case?

Further technical details

EF Core version: 3.1
Database provider: Microsoft.EntityFrameworkCore.SqlServer
Target framework: .NET Core 3.1
Operating system: Windows 10
IDE: Visual Studio 2019 16.5.1)

@bdebaere
Copy link

@jons-aura Do not use .ToString(), use (string)(object) instead, i.e. y.StringColumn+ "-" + (string)(object)y.NumberColumn) == x.tmr.OtherSideOfTheJoin.
See #20604.

@jons-aura
Copy link
Author

@bdebaere That didn't help. It's still generating a cast to nvarchar(3).

@smitpatel
Copy link
Member

EF takes type mapping for y.StringColumn and applies it to NumberColumn when generating cast.

@jons-aura
Copy link
Author

jons-aura commented Apr 23, 2020

I can kinda see why it would do that and that column is an nvarchar(3), but I think my use case (ignoring the join part of things) is valid and this breaks it. I can see someone wanting to concatenate a character code and a number, say a dimension and a unit of measure e.g. "5.5ft", and it would break in that scenario for quite small numbers. If there is a workaround that doesn't also break SQLite provider query generation or involve changing the column definition of the string column I'm open to that for now.

@ajcvickers
Copy link
Member

This is essentially a duplicate of #14719 since the normal type inference rules are not appropriate for concatenation, of which this is a form.

Another workaround it to lie to EF Core about the size of the column--for example, configure it to be nvarchar(15) or whatever you deem is safe. This is unlikely to impact anything EF does outside of migrations (which you're not using) and cases like this.

@ajcvickers ajcvickers reopened this Oct 16, 2022
@ajcvickers ajcvickers closed this as not planned Won't fix, can't repro, duplicate, stale Oct 16, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants