2016-12-17 27 views
9

Tôi đang cố gắng xây dựng một kho lưu trữ chung với người lập bản đồ. Tuy nhiên, tôi có một số khó khăn để thực hiện các hoạt động CRUD.Kho lưu trữ chung với người lập bản đồ

Dưới đây là một số mã từ kho:

public class GenericRepository<TEntity> : IGenericRepository<TEntity> where TEntity : class 
{ 
    internal IDbConnection Connection 
    { 
     get 
     { 
      return new SqlConnection(ConfigurationManager.ConnectionStrings["SoundyDB"].ConnectionString); 
     } 
    } 

    public GenericRepository(string tableName) 
    { 
     _tableName = tableName; 
    } 

    public void Delete(TEntity entity) 
    { 
     using (IDbConnection cn = Connection) 
     { 

      cn.Open(); 
      cn.Execute("DELETE FROM " + _tableName + " WHERE [email protected]", new { ID = entity.Id }); 
     } 
    } 
} 

Như bạn thấy, delete-phương pháp của tôi mất một TEntity như tham số mà là một paramter của kiểu lớp.

tôi gọi Xóa-phương pháp của tôi từ UserRepository của tôi như thế này:

public class UserRepository : GenericRepository<User>, IUserRepository 
{ 
    private readonly IConnectionFactory _connectionFactory; 

    public UserRepository(IConnectionFactory connectionFactory) : base("User") 
    { 
     _connectionFactory = connectionFactory; 
    } 

    public async Task<User> Delete(User model) 
    { 
     var result = await Delete(model); 
     return result; 
    } 
} 

Cái này là tôi không thể viết entity.Id ở Xóa-opration của tôi trong kho lưu trữ chung của tôi. Tôi gặp lỗi. Vậy làm thế nào tôi có thể dễ dàng thực hiện các hoạt động CRUD như thế này?

Đây là thông báo lỗi:

TEntity does not contain a definition of "Id" and no extension method "Id" accepting a argument of type "TEntity" could be found 
+0

Khi bạn gặp lỗi và bạn đặt câu hỏi về lỗi đó, bạn cần bao gồm lỗi đó. Một lỗi xảy ra trong thời gian chạy trường hợp này được gọi là một 'ngoại lệ' (* đây là cách các lỗi tự biểu hiện trong .net *). Bao gồm 'Message',' Type', 'StackTrace', và lặp lại điều này một cách đệ quy trên' InnerException'. Sử dụng liên kết chỉnh sửa trên câu hỏi của bạn để bao gồm chi tiết đó, không bao gồm chi tiết đó làm nhận xét.Vui lòng đọc [Làm cách nào để tôi đặt câu hỏi hay] (http://stackoverflow.com/help/how-to-ask). – Igor

+0

@Igor: Đây không phải là lỗi thời gian chạy. Kiểm tra câu hỏi đã cập nhật của tôi. – Bryan

+0

Tất cả các loại mà bạn sử dụng có một thuộc tính công khai của loại 'int' có tên là' Id' không? – Igor

Trả lời

7

Xác định giao diện như vậy.

public interface ITypeWithId { 
    int Id {get;} 
} 

Và đảm bảo loại User của bạn triển khai giao diện đó.

Bây giờ, hãy áp dụng nó vào lớp học của bạn như một ràng buộc chung.

public class GenericRepository<TEntity> : IGenericRepository<TEntity> where TEntity : class, ITypeWithId 

Nếu bạn có các loại được lưu trữ trong kho nhưng không có một tài sản Id sau đó hãy loại hạn chế xóa của bạn cụ thể cho các phương pháp và không phải là lớp học. Điều này sẽ cho phép bạn vẫn sử dụng cùng một loại kho lưu trữ ngay cả với các loại có thể khóa trên một thứ khác như chuỗi hoặc khóa phức hợp (multi).

public void Delete<T>(T entity) where T : class, ITypeWithId 
{ 
    using (IDbConnection cn = Connection) 
    { 

     cn.Open(); 
     cn.Execute("DELETE FROM " + _tableName + " WHERE [email protected]", new { ID = entity.Id }); 
    } 
} 
+0

Cảm ơn bạn :). Vì vậy, nếu tôi muốn có được một người dùng bằng tên người dùng, tôi nên làm truy vấn này trong UserRepository của tôi thay vì kho lưu trữ chung? – Bryan

+0

@Bryan - Nếu bạn có các hoạt động cụ thể đối với thực thể không phải là chung chung, chúng phải được bao gồm trong các loại kho lưu trữ có nguồn gốc như 'UserRepository'. Chỉ các hoạt động phổ biến có thể được định nghĩa trong GenericRepository của bạn. – Igor

+0

Cảm ơn bạn. Và lớp người dùng của tôi có triển khai giao diện mà bạn đã cung cấp không? Lớp người dùng Là thực thể – Bryan

1

bạn phải xác định một giao diện như dưới đây

public interface IIdentityEntity 
{ 
    public int Id { get; set;} 
} 

tất cả các đơn vị của bạn mà muốn sử dụng lớp, phải thực hiện các IIdentityEntity.

và dòng đầu tiên nên được thay đổi như sau

và những gì là vấn đề là bạn chỉ miêu tả TEntity như lớp và lớp không có một Id trong mô tả của nó vì vậy bạn phải thông báo cho trình biên dịch mà loại Generic đã triển khai Giao diện chứa trường Id bên trong nó

+0

Vì vậy, lớp người dùng của tôi phải triển khai giao diện này? – Bryan

+0

tất cả các lớp muốn sử dụng xóa chung phải triển khai giao diện – Khatibzadeh

2

Vui lòng không làm điều này! Kho lưu trữ chung của bạn thêm nhiều nhầm lẫn hơn giá trị. Đó là mã dễ vỡ (chuỗi ký tự cho _tableName, lỗi truyền không hợp lệ trên tham số id) và giới thiệu lỗ hổng bảo mật định hình (chèn sql qua _tableName). Nếu bạn đã chọn Dapper, đó là bởi vì bạn muốn kiểm soát sql của bạn, do đó, nó không có ý nghĩa để tạo sql bạn gửi đến Dapper.

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