簡體   English   中英

實體框架從表達式生成錯誤的參數類型

[英]Entity Framework generating wrong parameter type from expression

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");

Documento.Numero documento是一個字符串。 數據庫表中的相應字段是varchar(50)。 numeroOriginal也是一個字符串。

這個代碼用於存儲庫中的obter(get)

private T Obter(Expression<Func<T, bool>> filtro, string propriedadesIncluidas)
    {
        IQueryable<T> query = dbSet;

        if (filtro != null)
            query = query.Where(filtro);

        if (!string.IsNullOrWhiteSpace(propriedadesIncluidas))
        {
            foreach (var includeProperty in propriedadesIncluidas.Split
                (new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries))
                query = query.Include(includeProperty);
        }

        return query.FirstOrDefault();
    }

當EF創建sql查詢時,它會創建此查詢(從debbuger獲取)

SELECT     [Extent1].[id] AS [id],     [Extent1].[numero_documento] AS [numero_documento],     
-- Removed for clariry
FROM [dbo].[DOCUMENTO] AS [Extent1]    
WHERE [Extent1].[numero_documento] = (CASE WHEN (@p__linq__0 IS NULL) THEN N'' ELSE @p__linq__0 END)

更換參數后,轉換為

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'

兩者都有效,但第二個比第一個更快(我意味着很多)。 我在SQL管理工作室中運行。 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());

我從EF獲得了一條SQL語句:

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

過濾器顯示為N'12'

如果我刪除不必要的強制轉換(DB列是varchar(50)並且正在使用的變量是一個字符串。)

Expression<Func<Course, bool>> where = (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。

您可以在構建表達式時嘗試從項目中刪除轉換。 如果需要轉換值,請嘗試僅轉換值,而不是實體端屬性:即

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.

除此之外,您使用的是什么版本的Entity Framework?

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM