Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/264.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 实体框架从表达式生成错误的参数类型_C#_Sql Server_Entity Framework - Fatal编程技术网

C# 实体框架从表达式生成错误的参数类型

C# 实体框架从表达式生成错误的参数类型,c#,sql-server,entity-framework,C#,Sql Server,Entity Framework,EF正在创建一个接收int作为参数的查询。它应该是一个varchar 我有一个生成表达式的C代码 Expression<Func<Documento, bool>> query = (t => (string)t.NumeroDocumento.ToString() == (string)numeroOriginal.ToString()); var documento = documentoRepository.Obter(query, propriedades

EF正在创建一个接收int作为参数的查询。它应该是一个varchar

我有一个生成表达式的C代码

Expression<Func<Documento, bool>> query = (t => (string)t.NumeroDocumento.ToString() == (string)numeroOriginal.ToString());

var documento = documentoRepository.Obter(query, propriedadesIncluidas: "PapelPessoa.Pessoa");
替换参数后,这将转换为

SELECT     [Extent1].[id] AS [id],     [Extent1].[numero_documento] AS [numero_documento],     
-- Removed for clariry
FROM [dbo].[DOCUMENTO] AS [Extent1]    
WHERE [Extent1].[numero_documento] = 47837
正确的查询应该是

SELECT     [Extent1].[id] AS [id],     [Extent1].[numero_documento] AS [numero_documento],     
-- Removed for clariry
FROM [dbo].[DOCUMENTO] AS [Extent1]    
WHERE [Extent1].[numero_documento] = '47837'
两种方法都有效,但第二种方法比第一种方法快得多(我的意思是快得多)。我在sqlmanagementstudio中运行了这两个程序。EF获取参数的类型是否错误?我该如何解决这个问题?我需要更改代码还是数据库?表的EF配置是否错误

这是EF对象:

[Table("DOCUMENTO")]
    public class Documento : EntidadeBase
    {

        [Column("numero_documento", TypeName = "varchar")]
        [Display(Name = "Numero")]
      public string NumeroDocumento { get; set; }

// removed for clarity
}
这是桌子

CREATE TABLE [dbo].[DOCUMENTO](
    [id] [int] IDENTITY(1,1) NOT NULL,
    [numero_documento] [varchar](50) NULL,
-- removed for clarity
}

我怀疑在这个实体/列的周围配置了一些不同的东西,或者可能是上下文导致了这个问题。我试图重现这个问题,但没有遇到同样的问题:

我在我的一个测试表中添加了一个varchar列,并将数值输入其中进行搜索

使用与您拥有的相同的类型转换:

Expression<Func<Course, bool>> where = (x => (string)x.SomeNumber.ToString() == (string)testId.ToString());
过滤器的读数为N'12'

如果我删除了不必要的强制转换(DB列是varchar(50),所使用的变量是字符串。)

表达式,其中=(x=>x.SomeNumber==testId)

结果:

exec sp_executesql N'SELECT 
    [Extent1].[CourseId] AS [CourseId], 
    [Extent1].[Name] AS [Name], 
    [Extent1].[SomeNumber] AS [SomeNumber]
    FROM [dbo].[Courses] AS [Extent1]
    WHERE ([Extent1].[SomeNumber] = @p__linq__0) OR (([Extent1].[SomeNumber] IS NULL) AND (@p__linq__0 IS NULL))',N'@p__linq__0 nvarchar(4000)',@p__linq__0=N'12'
go
同样,N'12'

当我用TypeName=“varchar”对列进行属性化时,nvarchar(4000)和N'12'变成了varchar(8000)和'12'。然而,在第二个例子中,在第一个例子中(使用额外的强制转换),奇怪的是,它仍然将参数称为nvarchar

在构建表达式时,是否可以尝试从项目中删除强制转换。如果需要强制转换该值,请尝试仅强制转换该值,而不是实体端属性: 即

expressionquery=(t=>t.NumeroDocumento==numeroOriginal);

expressionquery=(t=>t.NumeroDocumento==numeroOriginal.ToString());//如果数字原始可能不是字符串。
除此之外,您使用的是什么版本的实体框架?

您所说的“替换参数后”是什么意思?参数不会被替换,而是用作变量。
@p_uulinq_u0
参数的类型应该是
varchar
nvarchar
,并且
=@p_ulinq_u0
相当于
='47837'
=N'47837'
,而不是
=47837
。问题应该与参数嗅探或
nvarchar
varchar
转换有关。尝试设置
this.Configuration.UseDatabaseNullSemantics=true
DbContext
派生类构造函数中。
Expression<Func<Course, bool>> where = (x => (string)x.SomeNumber.ToString() == (string)testId.ToString());
exec sp_executesql N'SELECT 
    [Extent1].[CourseId] AS [CourseId], 
    [Extent1].[Name] AS [Name], 
    [Extent1].[SomeNumber] AS [SomeNumber]
    FROM [dbo].[Courses] AS [Extent1]
    WHERE ((CASE WHEN ([Extent1].[SomeNumber] IS NULL) THEN N'''' ELSE [Extent1].[SomeNumber] END) = (CASE WHEN (@p__linq__0 IS NULL) THEN N'''' ELSE @p__linq__0 END)) OR ((CASE WHEN ([Extent1].[SomeNumber] IS NULL) THEN N'''' ELSE [Extent1].[SomeNumber] END IS NULL) AND (CASE WHEN (@p__linq__0 IS NULL) THEN N'''' ELSE @p__linq__0 END IS NULL))',N'@p__linq__0 nvarchar(4000)',@p__linq__0=N'12'
go
exec sp_executesql N'SELECT 
    [Extent1].[CourseId] AS [CourseId], 
    [Extent1].[Name] AS [Name], 
    [Extent1].[SomeNumber] AS [SomeNumber]
    FROM [dbo].[Courses] AS [Extent1]
    WHERE ([Extent1].[SomeNumber] = @p__linq__0) OR (([Extent1].[SomeNumber] IS NULL) AND (@p__linq__0 IS NULL))',N'@p__linq__0 nvarchar(4000)',@p__linq__0=N'12'
go
Expression<Func<Documento, bool>> query = (t => t.NumeroDocumento == numeroOriginal);
Expression<Func<Documento, bool>> query = (t => t.NumeroDocumento == numeroOriginal.ToString()); // if numeroOriginal may not be a string.