使用存储库模式创建多对多关系 [关闭]

Posted

技术标签:

【中文标题】使用存储库模式创建多对多关系 [关闭]【英文标题】:Creating Many-to-many relationship with repository pattern [closed] 【发布时间】:2020-04-08 02:20:38 【问题描述】:

我有一个看起来像这样的 Dish 和 Category 表:

public class Dish 

    public int Id  get; set; 

    [Required]
    public string Name  get; set; 

    [Required]
    public decimal Price  get; set; 

    public string Description  get; set; 

    public ICollection<UserDish> UserDishes  get; set; 

    public ICollection<DishCategory> DishCategories  get; set; 


public class Category 

    public int Id  get; set; 

    [Required]
    public string Name  get; set; 

    public ICollection<DishCategory> DishCategories  get; set; 


我有每个接口和实现

public class EFDishRepository : IDishRepository 

    private ApplicationDbContext _context;

    public EFDishRepository(ApplicationDbContext ctx) 
        _context = ctx;
    

    public IQueryable<Dish> Dishes => _context.Dishes;


public class EFCategoryRepository : ICategoryRepository 
    private readonly ApplicationDbContext _context;

    public EFCategoryRepository(ApplicationDbContext ctx) 
        _context = ctx;
    

    public IQueryable<Category> Categories => _context.Categories;

我有一个由 fluent API 映射的多对多关系。

我的问题是处理DishCategory 表的最佳做法是什么?

我是否应该创建单独的存储库来处理它,因为从DishCategory 方面处理它感觉不对?

【问题讨论】:

这里是回购模式的小指南 -> programmingwithmosh.com/net/… 。返回 IQueryable 通常是“不好的” 做法。还有什么对你有意义?如果这是您所要求的,那么在一个存储库中拥有 2 个域并没有错。确保让 repo 的消费者知道这一点,因为这是一个更昂贵的查询。 @panoskarajohn 我应该改为使用不同的方法在存储库中进行所有过滤吗?我在问拥有一个加入表存储库是否合适,因为我在任何地方都找不到示例 在你的 repo 中加入表格是可以的。我通常为过滤做的是将filter of type Expression&lt;Func&lt;MyClass,bool&gt;&gt; 作为参数并让它处理我在回购中的所有过滤。另外,对于您的回购,请确保您有单独的方法。对于您的示例,将所有dishes with categories 发送给我是有意义的。我将在我的 DishRepo 中使用两种方法,一种称为 GetAllDishes,另一种称为 GetAllDishesWithCategories,我会将过滤器 Expression&lt;Func&lt;Dish,bool&gt;&gt; 传递给两者。这有意义吗? 我真的很喜欢这个 -> albahari.com/nutshell/predicatebuilder.aspx。它显示了 LinqKit(您不必使用它)。它展示了表达式树如何与 Linq 一起使用。 另外,如果您对自己的代码仍有疑问 -> codereview.stackexchange.com 您可以获得代码审查。 【参考方案1】:

处理 DishCategory 表的最佳做法是什么?

它们应该在同一个存储库中。你的ApplicationDbContext 是一个非常好的存储库。首先没有理由将它包装在单独的存储库类中。

如果您走这条路,您将不断地在您的存储库中添加和更改方法以在您的应用程序中实现业务逻辑,并且您的存储库最终将充满属于存储库之外的代码,例如查询和事务。

如果您想要一个单一实体存储库,您应该至少有一个方法可以访问 DbContext 以访问其他实体。这是一个简单的单实体接口的想法,使用 C# 8 的新默认接口实现功能。

public interface IRepository<T> where T:class

    public DbSet<T> Set
    
        get 
        
            var db = (DbContext)this;
            return db.Set<T>();

        
    
    public T Find(int id)
    
        return Set.Find(id);
            

    //. . .

【讨论】:

以上是关于使用存储库模式创建多对多关系 [关闭]的主要内容,如果未能解决你的问题,请参考以下文章

具有存储库模式的实体框架,将数据插入到具有多对多关系的表中

Spring 数据存储库不会以多对多关系保存数据

在控制器中创建多对多模型的模式

多对多实体框架和存储库模式插入/更新

Symfony 查询生成器(多对多关系)

多对多关系的适当表模式和对唯一性的关注