【问题标题】:Is it bad practice to filter by ID within the repository pattern在存储库模式中按 ID 过滤是不好的做法
【发布时间】:2013-06-17 23:27:39
【问题描述】:

我正在使用带有 Entity Framework 5 的 ASP.NET MVC4

基本上每个控制器操作结果通过登录的用户的公司 ID 过滤数据库结果。我刚刚开始实现存储库模式来返回模型,而不是直接从控制器中过滤 DbContext。 (将 companyID 传递到存储库以过滤方法的结果)

我有一种有趣的感觉,即这样做是不好的做法,但一直无法找到有关该主题的任何信息。我将在下面插入我当前代码的基本版本,我将不胜感激任何关于它是否是不好的做法以及为什么会这样的信息。

IBookingSystemRepository.cs

public interface IBookingSystemRepository : IDisposable
{
    IEnumerable<Appointment> GetAppointments();
    IEnumerable<Appointment> GetAppointments(bool includeDeleted);
    IEnumerable<Client> GetClients();
    IEnumerable<Client> GetClients(bool includeDeleted);
    void Save();
}

BookingSystemRepository.cs

public class BookingSystemRepository : IBookingSystemRepository
{
    private BookingSystemEntities db;
    int CompanyID;

    public BookingSystemRepository(BookingSystemEntities context, int companyID)
    {
        this.db = context;
        this.CompanyID = companyID;
    }

    public IEnumerable<Appointment> GetAppointments()
    { return GetAppointments(false); }

    public IEnumerable<Appointment> GetAppointments(bool includeDeleted)
    {
        return includeDeleted
            ? db.Appointments.Where(a => a.User.CompanyID == CompanyID)
            : db.Appointments.Where(a => a.User.CompanyID == CompanyID && a.Deleted.HasValue);
    }

    public IEnumerable<Client> GetClients()
    { return GetClients(false); }

    public IEnumerable<Client> GetClients(bool includeDeleted)
    {
        return includeDeleted
            ? db.Clients.Where(c => c.CompanyID == CompanyID)
            : db.Clients.Where(c => c.CompanyID == CompanyID && c.Deleted.HasValue);
    }

    public void Save()
    {
        db.SaveChanges();
    }

    public void Dispose()
    {
        if (db != null)
            db.Dispose();
    }
}

TestController.cs

public class TestController : Controller
{
    private BookingSystemEntities db = new BookingSystemEntities();

    public ActionResult AppointmentsList()
    {
        var user = db.Users.Single(u => u.Email == User.Identity.Name);
        IBookingSystemRepository rep = new BookingSystemRepository(db, user.CompanyID);
        return View(rep.GetAppointments());
    }
}

提前感谢您的帮助:)

【问题讨论】:

    标签: c# .net entity-framework asp.net-mvc-4 entity-framework-5


    【解决方案1】:

    这是一个多租户应用程序。需要过滤以保持每个公司的数据分开。你的方法是正确的;如果可能,提供已经过滤的上下文,而不是在下游存储库方法中单独过滤。

    【讨论】:

    • 非常感谢您的帮助和快速响应 :) 在将上下文传递到存储库之前,我什至没有考虑过滤上下文,我认为您的方法会让事情变得更简单!只是为了澄清一下,你的意思是让我创建一个新的 DbContext 类,它根据传递给构造函数的 ID 过滤所有 DbSet?
    • 这将是一个有趣的想法。如果你能把它拉下来就好了。不,我更多的是考虑一个存储库或 DBContextWrapper 类来为您的正常存储库提供数据。从安全的角度来看,提供 DBContext 的最佳方式是在您的数据库引擎中提供已过滤的视图。但我不知道你有多少时间。 :)
    • 所以本质上是在这个和 DbContext 之间创建另一个存储库,将所有内容过滤到公司级别?您关于使用数据库视图过滤它的想法可能是最好的选择,但我目前没有时间这样做。无论如何,非常感谢您的帮助罗伯特。 :)
    猜你喜欢
    • 2023-03-24
    • 2023-03-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-04-25
    • 1970-01-01
    • 2010-10-11
    相关资源
    最近更新 更多