Entity Framework 5 TSQL не совместим с SQL 2005, вызывая хранимые процедуры

Я использую Entity Framework 5, код сначала для базы данных SQL 2005. У меня есть хранилище с методом, который выполняет хранимую процедуру. Метод выглядит следующим образом;

   public IEnumerable<PossibleDuplicateCustomer> GetPossibleDuplicates(Customer customer)
    {

        return DbContext.Database.SqlQuery<PossibleDuplicateCustomer>(
            "EXEC SearchPotentialDuplicates @CustomerId = {0}, @FirstName = {1}, @LastName = {2}, @dob = {3}",
            customer.CustomerId,
            customer.CustomerFirstName,
            customer.CustomerLastName,
            customer.Dob);
    }

Другой вариант, который я попробовал, есть;

    public IEnumerable<PossibleDuplicateCustomer> GetPossibleDuplicates(Customer customer)
    {
        return DbContext.Database.SqlQuery<PossibleDuplicateCustomer>(
            "SearchPotentialDuplicates @CustomerId, @FirstName, @LastName, @dob",
            new SqlParameter("CustomerId", customer.CustomerId),
            new SqlParameter("FirstName", customer.CustomerFirstName),
            new SqlParameter("LastName", customer.CustomerLastName),
            new SqlParameter("dob", customer.Dob));
    }

Когда я выполняю это - я получаю ошибку;

System.Data.SqlClient.SqlException (0x80131904): неправильный синтаксис рядом с "SearchPotentialDuplicates".

Так что я взял сгенерированный SQL с помощью минипрофилера, который дал мне;

DECLARE @p0 int = 12644,
    @p1 nvarchar(4) = N'adam',
    @p2 nvarchar(3) = N'ant',
    @p3 datetime = '1951-11-01T00:00:00'

EXEC SearchPotentialDuplicates @CustomerId = @p0, @FirstName = @p1, @LastName = @p2, @dob = @p3   

Я попытался скопировать и вставить это в ssms, и это дало ошибку, потому что синтаксис объявления и назначения в одной строке не поддерживается

Msg 139, Level 15, State 1, Line 0
Cannot assign a default value to a local variable.
Msg 137, Level 15, State 2, Line 6
Must declare the scalar variable "@p0".

Это новая вещь sql 2008 ( http://blogs.microsoft.co.il/blogs/bursteg/archive/2007/12/05/sql-server-2008-t-sql-declare-and-set-in-the-same-statement.aspx) и не поддерживается в SQL 2005- Изменение запроса на;

DECLARE @CustomerId int  ,
    @FirstName nvarchar(25),
    @LastName nvarchar(25) ,
    @dob datetime 

SET @CustomerId  = 12645
SET @FirstName  = N'adam'
SET @LastName  = N'ant'
SET @dob  = '1951-11-01T00:00:00'

exec SearchPotentialDuplicates @CustomerId, @FirstName, @LastName, @dob  

работает отлично! Так что мой вопрос: как получается, что сущностная структура использует этот ментальный синтаксис? Я немного погуглил, и люди говорят о ProviderManifestToken, но это, по-видимому, необходимо только при переходе на совершенно другую платформу, такую ​​как sql ce, а не между версиями sql. Итак, есть ли параметр, который я пропускаю, или я могу изменить запрос, чтобы он выполнялся по-другому?

Спасибо всем!

1 ответ

Решение

Наконец-то все заработало - я попытался, следуя этой статье http://blog.oneunicorn.com/2012/04/21/code-first-building-blocks/ (Артур Виккерс из команды Entity Framework) рассказать DbContext использовать синтаксис SQL 2005 - поэтому, когда я создаю контекст, я делаю это;

var builder = new DbModelBuilder();
builder.Entity<PossibleDuplicateCustomer>();
var model = builder.Build(new DbProviderInfo("System.Data.SqlClient", "2005"));
_compiledSql2005Model = model.Compile();

// OverdriveDbContext : DbContext
var context = new OverdriveDbContext(
    nameOrConnectionString: "OverdriveConnectionString", 
    model: _compiledSql2005Model);

Это теперь выполняет следующий SQL;

exec sp_executesql N'EXEC SearchPotentialDuplicates @CustomerId, @FirstName, @LastName, @dob',N'@CustomerId int,@FirstName nvarchar(4),@LastName nvarchar(3),@dob datetime',@CustomerId=12645,@FirstName=N'adam',@LastName=N'ant',@dob='1951-11-01 00:00:00'

который прекрасно работает в SQL 2005. Однако, предостережение- MiniProfiler (который я использую для мониторинга вызовов инфраструктуры сущностей) неправильно показывает SQL, выполненный как:

DECLARE @CustomerId int = 12645,
    @FirstName nvarchar(4) = N'adam',
    @LastName nvarchar(3) = N'ant',
    @dob datetime = '1951-11-01T00:00:00'

EXEC SearchPotentialDuplicates @CustomerId, @FirstName, @LastName, @dob   

что остановило меня, заметив, что я исправил это на несколько часов! Таким образом, урок, который есть в SQL-мониторинге MiniProfiler, не заменит старого доброго Sql Profiler!

Другие вопросы по тегам