2012-07-10 33 views
5

Tôi đang phát triển một ứng dụng web nhiều bên thuê (ngăn xếp: MVC 4 + Khuôn khổ thực thể 4.3). Yêu cầu của tôi khá đơn giản: mỗi người thuê có cùng một giao diện người dùng và CodeBase.Giải pháp cho một ứng dụng web nhiều người thuê đơn giản với khung tổ chức

Trong cơ sở dữ liệu của tôi, tôi có một số bảng có trường TenantId (và các bảng khác không có).

Tôi đã thiết lập một kho lưu trữ chung rất đơn giản:

public class GenericRepository<TEntity> where TEntity : class 
{ 
    internal Database.CRMEntities context; 
    internal DbSet<TEntity> dbSet; 
    internal int tenantId; 

    public GenericRepository(Database.CRMEntities context) 
    { 
     this.context = context; 
     this.dbSet = context.Set<TEntity>(); 
     this.tenantId = 1; 
    } 

Tôi muốn "nhận" phương pháp để lọc cho tenantId tôi. Phương pháp chèn, cập nhật và xóa của tôi cũng nên hạn chế TenantId thích hợp.

Đối tượng của tôi là các lớp POCO được tạo tự động.

Tôi đã xem xét các giải pháp sau:

1- GenericRepository nên triển khai giao diện "ITenant" định nghĩa TenantId. Vấn đề là một số thực thể không có tài sản TenantId. Ngoài ra, tôi không thực sự muốn thay đổi mẫu T4 tôi sử dụng để tạo ra đối tượng POCO để làm cho họ thực hiện giao diện của tôi

2- Reflection (nhưng tất nhiên EF không thể dịch nó vào một câu lệnh SQL)

if (typeof(TEntity).GetProperty("TenantId") != null) 
      query = query.Where(x => (int) (x.GetType().GetProperty("TenantId").GetValue(x, null)) == tenantId); 

Bạn sẽ làm gì trong trường hợp của tôi? Tôi sẵn sàng xem xét lại kiến ​​trúc của mình nếu cần.

Cảm ơn, Nicola

Trả lời

5

Bạn có thể làm việc kiểm tra phản ánh và sau đó tự tạo ra một cây biểu rằng EF thể hiểu được.

Ví dụ:

int tenantId = 5; 

var tenantIdInfo = typeof(TEntity).GetProperty("TenantId"); 

if (tenantIdInfo != null) 
{ 
    var entity = Expression.Parameter(typeof(TEntity), "it"); 

    var predicate = (Expression<Func<TEntity, bool>>)Expression.Lambda(
     Expression.Equal(
      Expression.MakeMemberAccess(entity, tenantIdInfo), 
      Expression.Constant(tenantId, typeof(int))), 
     entity); 

    query = query.Where(predicate); 
} 
+0

Cảm ơn bạn đã trả lời. Một biểu thức sẽ hoạt động ... và đó là một đoạn mã khá đơn giản để quản lý một vấn đề phức tạp. Tôi đã tự hỏi ... là phản ánh "chậm" hoặc tôi có thể sử dụng nó mà không có bất kỳ vấn đề? –

+0

Phản ánh không có tác động đáng kể đến hiệu suất, nhưng bạn sẽ cần phải đo lường nó cho kịch bản cụ thể của bạn để xem liệu nó có được chấp nhận hay không. –

+0

Tôi chạy một số thử nghiệm: truy vấn chọn lặp lại 1000 lần và chỉ trả về một hàng chậm hơn khoảng 5%. Đó không phải là một thử nghiệm hoàn chỉnh, nhưng bây giờ là đủ. Tôi sẽ đánh dấu câu hỏi của mình là đã trả lời nếu không có ý tưởng nào tốt hơn trong một vài ngày. Cảm ơn! –

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