2015-01-15 35 views
8

Tôi đang làm việc trên một ứng dụng hiện có, sử dụng mẫu Lặp lại Chung và cơ sở dữ liệu EF6 trước. Tôi đang gọi một proc được lưu trữ trả về một loại phức tạp không phải là một thực thể hiện có trong các mô hình thực thể của tôi và do đó tôi không chắc chắn nên cung cấp loại nào.Sử dụng Kho lưu trữ Chung và Thủ tục được Lưu trữ

Đây là cách sp của tôi đã được gọi từ lớp dịch vụ của tôi

_unitOfWork.Repository<Model>() 
      .SqlQuery("sp_Get @FromDateTime, @ToDateTime, @CountyId", 
         new SqlParameter("FromDateTime", SqlDbType.DateTime) { Value = Request.FromDateTime }, 
         new SqlParameter("ToDateTime", SqlDbType.DateTime) { Value = Request.TripToDateTime }, 
         new SqlParameter("CountyId", SqlDbType.Int) { Value = Convert.ToInt32(Request.County) } 
      ).ToList(); 

Tôi tạo ra một thực thể trong lớp dữ liệu của tôi để ánh xạ hoặc những gì là phương pháp tốt nhất cho các thủ tục được lưu trữ trở lại loại phức tạp. Nếu như vậy là có bản đồ tùy chỉnh cần thiết hoặc là nó chỉ là một trường hợp của việc tạo ra các lớp Entity

cảm ơn bạn

Trả lời

11

Nếu bạn có một thực thể với những lĩnh vực bạn có thể gọi phương thức sqlquery như bạn thấy ở trên, nếu không muốn nói, sau đó tôi khuyên bạn nên tạo một lớp mới để lập bản đồ kết quả:

public class Result 
{ 
    public int CountyId { get; set; } 

    public DateTime FromDateTime { get; set; } 

    public DateTime ToDateTime { get; set; } 
} 

tôi không biết làm thế nào được thực hiện mô hình UnitOfWork trong trường hợp của bạn, nhưng tôi cho rằng bạn có quyền truy cập vào bối cảnh của bạn. Trong lớp UnitOfWork của bạn, bạn có thể tạo ra một phương pháp chung chung như thế này:

public class UnitOfWork 
{ 
    private YourContext Context { get; set; } 

    public DbRawSqlQuery<T> SQLQuery<T>(string sql, params object[] parameters) 
    { 
     return Context.Database.SqlQuery<T>(sql, parameters); 
    } 
} 

Bằng cách này, bạn có thể thực hiện các thủ tục lưu trữ của bạn như tôi hiển thị bên dưới:

var result= _unitOfWork.SqlQuery<Result>("sp_Get @FromDateTime, @ToDateTime, @CountyId", 
        new SqlParameter("FromDateTime", SqlDbType.DateTime) { Value = Request.FromDateTime }, 
        new SqlParameter("ToDateTime", SqlDbType.DateTime) { Value = Request.TripToDateTime }, 
        new SqlParameter("CountyId", SqlDbType.Int) { Value = Convert.ToInt32(Request.County) } 
     ).ToList(); 
+0

Cách tiếp cận này phù hợp với tôi. Tôi cũng phải thêm lớp/thực thể mới vào lớp ngữ cảnh của mình. 'public DbSet modelName {get; bộ; } 'và tôi đã phải đảm bảo thực thể mới của tôi có một' [key] 'và được thừa kế từ' EntityBase' – user2329438

7

Mục đích của Repository Pattern là trừu tượng đi lưu trữ & truy xuất dữ liệu để bảo vệ mã ứng dụng khách của bạn lớp nghiệp vụ (lớp dịch vụ trong trường hợp của bạn) không cần biết bất kỳ điều gì về cách dữ liệu được duy trì. Các câu lệnh SQL, ví dụ, sẽ chỉ tồn tại bên trong các lớp Repository của bạn, chứ không tồn tại trong suốt mã của bạn.

Nếu bạn hiển thị SQL, tên và tham số được lưu trữ vào mã máy khách của bạn sẽ không nhận được nhiều lợi ích từ Mẫu lưu trữ và nếu thực tế bạn không thể gọi nó là Kho lưu trữ. Bạn mất lợi ích khi có thể giả lập kho lưu trữ và kiểm tra lớp doanh nghiệp của bạn độc lập với lớp truy cập dữ liệu của bạn. Điều này có nghĩa là các bài kiểm tra tích hợp (yêu cầu một cá thể cơ sở dữ liệu đầy đủ) được yêu cầu để xác minh logic nghiệp vụ.

Hãy xem xét việc bao thanh toán lại để bạn có một lớp CountryRepository có phương thức GetCountry (int CountryId, DateTime fromDate, DateTime toDate) trả về một thực thể Quốc gia hoặc tương tự. Tôi nghĩ bạn sẽ đồng ý rằng khả năng đọc mã của bạn sẽ được cải thiện nhiều so với mã trong câu hỏi của bạn.

public class CountryRepository 
{ 
    public Country GetCountry(int CountryId, DateTime fromDate, DateTime toDate) 
    { 
    // EF or ADO.NET code here 
    } 
} 

Mã máy khách sau đó sẽ là ví dụ:

var c = unitOfWork.CountryRepository.GetCountry(1, DateTime.Now.AddYears(-1), DateTime.Now); 

Xem thêm này SO question

0

đường

IQueryable<Cm_Customer> customerQuery = _uow.SqlQuery<Cm_Customer>(@" DECLARE @UserId INT = {0} 
               EXEC Cm_GetCustomersByUserId @UserId", filter.UserId).AsQueryable(); 
    IQueryable<Cm_Customer> custs = customerQuery.IncludeMultiple(k => k.Cm_CustomerLocations, 
              k => k.Cm_CustomerSalesmans, 
              k => k.Cm_CustomerMachineparks, 
              k => k.Cm_CustomerAuthenticators, 
              k => k.Cm_CustomerInterviews, 
              k => k.Cm_CustomerRequest, 
              k => k.Cm_MachineparkRental).AsQueryable(); 

Trên cách không hoạt động trong trường hợp của tôi và tôi viết ở trên và điều này được làm việc cho tôi cho bất cứ ai trong trường hợp của tôi

0
public virtual IEnumerable<T> GetWithRawSql(string query, params object[] parameters) 
     { 
      return DbSet.SqlQuery(query, parameters).ToList(); 
     } 

Giao diện

IEnumerable<T> GetWithRawSql(string query, params object[] parameters); 
Các vấn đề liên quan