Cách gọi một thủ tục được lưu trữ trong EF Core 3.0 thông qua FromSqlRaw


10

Gần đây tôi đã chuyển từ EF Core 2.2 sang EF Core 3.0.

Thật không may, tôi đã không tìm thấy một cách để gọi một thủ tục được lưu trữ trả về một thực thể.

Trong EF Core 2.0, điều đó là có thể:

var spParams = new object[] { "bla", "xx" };
var createdPath = ModelContext.Paths.FromSql("AddNodeWithPathProc  @p0, @p1", spParams).Single();

Trong EF Core 3.0, phương thức FromSQLđược thay thế bằng FromSqlRaw. Tuy nhiên, tôi đã không quản lý để gọi thành công một thủ tục được lưu trữ và sau đó xử lý giá trị. Điều này hữu ích khi thủ tục được lưu trữ chèn dữ liệu vào cơ sở dữ liệu.

Vì vậy, trong EF Core 3.0, tôi sử dụng mã này:

var createdPath = ModelContext.Paths.FromSqlRaw("AddNodeWithPathProc @p0, @p1", spParams).Single();

nhưng nó sẽ đưa ra một ngoại lệ, vì SQL được tạo không hợp lệ và trông giống như thế này:

exec sp_executesql N'SELECT TOP(2) [p].[PathId], [p].[Level], [p].[NodeId], [p].[NodePath], [p].[NodePathString]
FROM (
     @sql @p0, @p1
) AS [p]',N'@p0 nvarchar(4000),@p1 nvarchar(4000), @sql nvarchar(100)',@p0=N'1a',@p1=N'', @sql=N'AddNodeWithPathProc'

Tôi đã thử khá nhiều biến thể, nhưng không thành công.

Tôi bắt đầu nghĩ rằng không thể chạy các thủ tục được lưu trữ với ModelContext.[IQueryable].FromSqlRaw. Theo tôi loại này đánh bại một trong những lý do chính FromSqlRawbởi vì, đối với các câu lệnh chọn bình thường, LINQ thường đủ tốt.

Có ai biết cách sử dụng các thủ tục được lưu trữ kết hợp với FromSqlRawtrong EF Core 3.0 không? Bất kỳ trợ giúp nào cũng được đánh giá rất cao.

Cảm ơn trước

PS: Tôi biết bạn có thể thực hiện một thủ tục được lưu trữ với this.Database.ExecuteSqlRaw(SQL, parameters). Tuy nhiên, theo cách đó, không thể truy xuất bất kỳ thực thể nào mà các thủ tục được lưu trữ truy vấn.


2
Hãy thử .ToList () thay vì .Single (). .Single () đang tạo trình bao bọc "TOP (2)".
David Browne - Microsoft

cách giải quyết tạm thời của tôi hiện tại là như sau: this.ModelContext.ExecuteRawSql ("EXEC AddNodeWithPathProc @ p0, @ p1", spParams); var createdPath = ModelContext.Paths.FromSqlRaw ("CHỌN TOP 1 * TỪ dbo.Path ĐẶT HÀNG B PathNG PathID DESC"). Single (); Tuy nhiên, đây không phải là một giải pháp chấp nhận được cho sản xuất.
Dan

có .. ToList () hoạt động .. cảm ơn rất nhiều :-)
Dan

Câu trả lời:


6

Giải pháp (nhờ David Browne, bạn nên đăng nó dưới dạng câu trả lời):

Thay thế Single bằng ToList hoạt động :-)

var createdPath = ModelContext.Paths.FromSqlRaw("AddNodeWithPathProc  {0}, {1}", nodeTitle, parentPathString).ToList();

1
var result=context.yourmodelclass.FromSqlInterpolated($"StoredProcedureName {param1},{param2}").tolist();

Bạn có thể thêm nhiều tham số nếu cần. Ghi chú:

  • bối cảnh => tên cơ sở dữ liệu của bạn.
  • yourmodel class => lớp trong thư mục mô hình bạn tạo để tìm nạp kết quả đầu ra từ kết quả thủ tục được lưu trữ.

0

Tôi không phải là nơi tôi có thể kiểm tra nhưng tôi nghĩ những điều sau đây sẽ hoạt động:

var createdPath = ModelContext.Paths.FromSqlRaw("AddNodeWithPathProc {0}, {1}", parm1 parm2).Single();

1
Không, cái này không hoạt động. Chỉ cần thử nghiệm nó. Sql không hợp lệ :-(. Tôi tin rằng nó có liên quan đến sql được tạo. Nếu tôi kiểm tra sql với profiler thì nó luôn tuân theo lược đồ: sp_executesql 'CHỌN * TỪ {mySqlPassedInMethod} biết làm thế nào để vượt qua trong một thủ tục được lưu trữ trong mã này. Vì vậy, phương thức .net phát hiện ra rằng chuỗi sql đã truyền là dành cho một thủ tục được lưu trữ và điều chỉnh sql được tạo theo hoặc có một cách trong T-SQL mà tôi không làm biết về (Tôi không phải là chuyên gia)
Dan

0

cố gắng tách riêng SqlParameter:

SqlParameter param1 = new SqlParameter("@p0","value");
SqlParameter param2 = new SqlParameter("@p1","value");

var createdPath = ModelContext.Paths.FromSqlRaw("AddNodeWithPathProc @p0 @p1", param1, 
param2).Single();

đăng một giải pháp cho bài viết bị xóa của bạn dưới đây.
jdweng

Chỉ cần thử nó và nó không thành công: hồ sơ sql)
Dan

@jdweng Cảm ơn rất nhiều :) Giải pháp này tôi có khi đăng nhập vào phần mềm của mình và tải xuống tệp XML được cập nhật mới nhất vào ngày cuối cùng nhưng tôi cần tất cả dữ liệu lịch sử về tỷ lệ mà không bỏ lỡ. Vì vậy, tôi có một tùy chọn khác để đặt ngày và tải xuống tệp excel với tỷ lệ, nhưng tôi không biết cách thực hiện điều đó. chạy một dịch vụ trên máy chủ? có thể người dùng sẽ không sử dụng phần mềm trong một tuần nên tôi đã bỏ lỡ cả tuần tỷ giá hối đoái.
ISTech

@ISTech: Xem trang sau: boi.org.il/en/Mmarket/Pages/explainxml.aspx bạn có thể thêm vào url một ngày. boi.org.il/currency.xml?rdate=20120101
jdweng

@ISTech: Tôi đã cập nhật mã dưới đây để thực hiện một phạm vi ngày.
jdweng

0

Nó cực kỳ lạ ngay trước vài ngày trước tôi có cùng một vấn đề và theo dõi bài đăng này. Tôi đã có cuộc gọi này:

 public IEnumerable<TableChange> GetTableLastChanges(string tableName, string keyColumn, out int synchronizationVersion)
    {
        var parameters = new[] {
            new SqlParameter("@table_name", SqlDbType.VarChar) { Direction = ParameterDirection.Input, Value = tableName },
            new SqlParameter("@key_column", SqlDbType.VarChar) { Direction = ParameterDirection.Input, Value = keyColumn },
            new SqlParameter("@synchronization_version", SqlDbType.BigInt) { Direction = ParameterDirection.InputOutput, Value = 0 }
        };

        var changes = this.TableChanges.FromSqlRaw("[dbo].[GetTableLastChanges] @table_name, @key_column, @synchronization_version OUTPUT", parameters).ToList();

        synchronizationVersion = Convert.ToInt32(parameters[2].Value);

        return changes;
    }

Ngay bây giờ mọi thứ đều ổn và cuộc gọi này hoạt động như mong đợi. Do đó, tôi nên thừa nhận rằng không có vấn đề gì với bộ dữ liệu và thông số trả về cho EF trên Core 3.


0

Có một cái nhìn ở đây:

https://github.com/DarioN1/SPToCore

Đây là một giàn giáo cho thủ tục lưu trữ, nó có thể giúp bạn làm việc với sp.

Đây không phải là thư viện phần thứ ba, nó đã tạo mã c # thuần để đưa vào dự án của bạn mở rộng dbContext hiện tại để cung cấp các phương thức thủ tục được lưu trữ, ánh xạ tham số và kết quả được phân loại.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.