简体   繁体   English

使用存储库模式加入DbSet

[英]Join DbSets with repository pattern

I have basic implementation of repository pattern with generic IRepository<T> which holds Add , Remove , Find , etc. and I have more precise repositories such as IActorRepository and IFilmRepository that derive from IRepository . 我已经使用通用的IRepository<T>实现了存储库模式的基本实现,该IRepository<T>拥有AddRemoveFind等。我还有更精确的存储库,例如从IRepository派生的IActorRepositoryIFilmRepository I have a method for search box that finds top 5 actors and films that match text from the search box. 我有一个用于搜索框的方法,该方法可以找到与搜索框中的文字相匹配的前5名演员和电影。

My question is how can I join these to repositories? 我的问题是如何将它们加入存储库? I need my method to be testable, so I don't want IQueryable in my method, just an interface I can mock later on. 我需要我的方法是可测试的,所以我不想在我的方法中使用IQueryable ,而只是以后可以模拟的接口。

The only thing for me that comes to mind is to create some kind of helper class such as public class FilmsActorsHelper: IFilmsActorsHelper . 对我而言,唯一想到的就是创建某种帮助程序类,例如public class FilmsActorsHelper: IFilmsActorsHelper I'm sure someone had an issue like that, what is a common practice here, how is it usually solved? 我确定有人遇到这样的问题,这是常见的做法,通常如何解决?

Method for which I need a solution: 我需要解决的方法:

[HttpPost]
public ActionResult SearchBoxChanged(string inputValue) {
    if (inputValue == null || inputValue.Length < 3)
        return Json(new List<string>());

    const int maxNamesCount = 5;
    var names = _filmRepository.Find(f => f.Name.Contains(inputValue)).Select(f => f.Name).Take(maxNamesCount).ToList();
    var remaining = maxNamesCount - names.Count;
    var actorNames = _actorRepository.Find(f => f.Name.Contains(inputValue)).Select(f => f.Name).Take(remaining).ToList();
    names.AddRange(actorNames);

    return Json(names);
}

Also, because I have ToList() I suspect it will pull everything from database, right? 另外,因为我有ToList() ,所以我怀疑它会从数据库中提取所有内容,对吗?

Do not wrap a type that already implements a Repository pattern ( DbContext ) in your own Repository type(s). 不要在您自己的存储库类型中包装已经实现存储库模式( DbContext )的类型。 You are adding an unneeded abstraction that only makes your code more difficult to read and you have to jump through hoops to do simple things like joining tables. 您正在添加不必要的抽象,这只会使您的代码更难以阅读,并且您必须跳过箍来完成诸如连接表之类的简单操作。 Create a service instead that has an instance of your DbContext and do your work in there and return a result. 创建一个具有DbContext实例的服务,然后在其中进行工作并返回结果。 Consume that service from your Controller. 从您的控制器使用该服务。 Then you can join on whatever you want. 然后,您可以随心所欲地加入。

Services should encapsulate and expose business logic. 服务应封装并公开业务逻辑。 So if you want to return a list of films based on actor then you would have some method like Task<List<Film>> GetFilmsForActorAsync(string actor) that would do that. 因此,如果要基于演员返回电影列表,则可以使用Task<List<Film>> GetFilmsForActorAsync(string actor)来实现。 Do not try to wrap each entity in its own service, then you have added nothing of real value. 不要尝试将每个实体包装在其自己的服务中,否则您没有添加任何实际价值。

You can also split your services based on functionality and read/write. 您还可以根据功能和读/写拆分服务。 See CQRS pattern . 请参阅CQRS模式

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM