6

Tôi đang sử dụng Entity Framework 5, Mã đầu tiên chống lại cơ sở dữ liệu SQL 2005. Tôi có một kho lưu trữ, với một phương thức thực hiện một thủ tục lưu sẵn- Phương thức này trông như thế này;Khuôn khổ thực thể 5 TSQL không tương thích với SQL 2005 gọi thủ tục được lưu trữ

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

Một biến thể khác mà tôi đã thử là;

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

Khi tôi thực hiện điều này, tôi nhận được lỗi;

System.Data.SqlClient.SqlException (0x80131904): Cú pháp không đúng gần 'SearchPotentialDuplicates'.

Vì vậy, tôi đã lấy sql được tạo bằng miniprofiler- đã cho tôi;

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 

tôi đã cố gắng sao chép và dán này vào SSMS và nó đã cho một lỗi vì cú pháp khai báo và gán trong một dòng không được hỗ trợ

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". 

Đây là một mới sql 2008 điều (http://blogs.microsoft.co.il/blogs/bursteg/archive/2007/12/05/sql-server-2008-t-sql-declare-and-set-in-the-same-statement.aspx) và không hỗ trợ trong SQL 2005- Thay đổi truy vấn thành;

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 

hoạt động tốt! SO câu hỏi của tôi là làm thế nào đến khuôn khổ thực thể đang sử dụng cú pháp tinh thần này? Tôi đã thực hiện một số googling và mọi người nói về ProviderManifestToken nhưng điều này dường như chỉ cần thiết nếu đi đến một nền tảng hoàn toàn khác như ce sql, không phải giữa các phiên bản sql. Vì vậy, có một thiết lập tôi đang mất tích, hoặc tôi có thể thay đổi các truy vấn để buộc nó để thực hiện theo một cách khác nhau?

Cảm ơn tất cả!

+0

Có thể cho rằng, họ có thể đã cung cấp hỗ trợ cho SQL Server 2005 bằng cách sử dụng khai báo biến kiểu cũ, nhưng tôi sẽ không gọi đó là "cú pháp tinh thần"; Tôi nghĩ rằng nó nên được mọi người ưa thích cách tuyên bố một biến trong T-SQL, miễn là bạn không nhắm mục tiêu bất cứ điều gì cũ hơn SQL Server 2008. –

+1

haha ​​có, không làm cho tôi sai-nó chắc chắn là cú pháp sạch hơn-Đó là luôn luôn bugged tôi phải chia tờ khai/phân công trên hai dòng! Nhưng nó chỉ tốt hơn nếu nền tảng đích hỗ trợ nó! – Shawson

+1

Còn ADO.Net và SqlCommand thì sao? Bạn có thể viết một wrapper để gọi procs được lưu trữ bằng cách sử dụng phương pháp này. Tôi biết đó là phương pháp cũ và nó không trả lời câu hỏi của bạn, nhưng nó có thể giải quyết vấn đề của bạn. –

Trả lời

2

Cuối cùng đã làm việc này- Tôi đã thử làm theo bài viết này http://blog.oneunicorn.com/2012/04/21/code-first-building-blocks/ (bởi Arthur Vickers trong nhóm khung thực thể) để báo cho DbContext sử dụng cú pháp sql 2005- Vì vậy, khi tôi xây dựng bối cảnh, tôi làm điều này;

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

Điều này hiện thực thi SQL sau;

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' 

mà hoạt động hoàn hảo trong SQL 2005. Một lời cảnh báo mặc dù - MiniProfiler (mà tôi đang sử dụng để giám sát các cuộc gọi khuôn khổ tổ chức) không đúng cách thể hiện sql thực hiện như:

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 

mà đã ngăn tôi nhận ra rằng tôi đã sửa lỗi này trong vài giờ! Vì vậy, bài học có giám sát SQL của MiniProfiler không thay thế cho Sql Profiler cũ tốt!

Các vấn đề liên quan