Answer the question
In order to leave comments, you need to log in
I don't know how to prepare a repository, or is it just not very good?
Very often I meet articles and questions in the style of "best solutions/practices for asp.net mvc" and almost everywhere they talk about such a cool pattern as a repository, which is really very cool and gives a lot of abstraction and allows you to test whatever you want. Well, for example, the first link in Google:
https://www.asp.net/mvc/overview/older-versions/ge...
I understand why the pattern is needed, I don’t understand another:
1)
how to select from a list of entities .
Well, for example, I have a Log table in which I write all the actions of users, and there are really VERY many entries, a lot of entries. I need, for example, to get all the records for a specific user, or let's say for a certain period. How can I do it?
public IEnumerable<Student> GetLogs()
{
return context.Logs.ToList();
}
var logs = (from l in db.Logs
join u in db.Users on l.userID equals u.id
where u.roleID == 1
select new { l , u }).ToList();
Answer the question
In order to leave comments, you need to log in
Colleagues, good afternoon!
Why has no one mentioned the UnitOfWork pattern? The repository pattern becomes very convenient to use if:
When using such a bundle, you have:
Think right - this special class is UnitOfWork. It is "just like dbContext", only in this way you abstract from all sorts of EF, NHibernate and other ORMs. As a result, your business logic doesn't care what ORM you use.
It is enough to connect 1 UnitOfWork (and it is better to do this through dependency injection - DI - DependencyInjection using an IoC container, for example, Autofac, Ninject, Unity. I personally like Autofac more, if only because it has the most adequate and understandable documentation than Ninject and even more so Unity [no, this is not a topic for a holivar "who is better: Autofac / Ninject / Unity / ... - these are all conclusions from my personal experience]).
In any enterprise project, you need to think ahead, even if it is a "small online store" project. Because in a year this small online store can turn into a normal business with very high turnover and profit, and then if you don’t have a good abstract architecture , if you don’t have modularity, then any new task will be implemented with an increasing number of crutches, and any new task will lead to system instability and an increase in the degree of regression (verified!). But if you, as an architect, put modularity and abstraction of components into your system during development, then you will thereby simplify your life in the future, which means that after some time any task to change the system will be solved faster, more reliably, and this means that you will be able to charge more money as a developer for this (because the cost of new changes will be much lower). And if you also use unit testing in development, then by doing so you reduce the risk of regression in the behavior of your system, which, again, reduces the development cost for you personally. Believe me
Fat Lorry - I absolutely agree with you on this.
Michael mentioned the principle of single responsibility very to the point. 1 component - 1 responsibility. I noticed on my own - if you follow at least this principle, then the system automatically becomes modular. And since there are modules, then you can reduce the degree of connectivity between components using abstractions (interfaces and abstract classes). And since there is abstraction between components, then unit testing will only be a joy. Moreover, both a class and a whole project can act as a component. For example, some module of the system can be moved to a separate project, and then this project can be connected to another system during development. This increases the degree of code reuse (why do the same thing 2 times?).
Mikhail also indicated in a comment in which cases the repository can not be used. I'll add: in non-enterprise solutions. For example, you are making some simple website for yourself. Or for a friend. Or just to learn new technology.
It is advisable to read about the work of EF and IQuerable
in particular. With this interface and LINQ, you will be able to build queries (which render to native SQL) instead of just filtering collections.
private IQuerable<Student> GetLogs()
{
return context.Logs;
}
public IEnumerable<Student> GetLogsForStudent(int id, DateTime from, DateTime to)
{
return GetLogs().Where(x => x.Id == id
&& x.Date >= from
&& x.Date <= to)
.ToList();
}
dbcontext
it makes no sense to wet it, if only because it is nailed to EF. Changing a DBMS is not such a common practice, but abandoning ORM (and EF in particular) in favor of performance is a real case with increasing load.
I think if a small, new project in which all the data lies in the database, which is created from EF Code First, then there is no special need to use the repository. But for example, if today I take data from the database, and tomorrow I plan to receive it from api or some kind of NoSQL to which there is no ORM? Or maybe the entities that my application operates on are not at all similar to those that lie in the database or are "collected" from several sources?
It is not necessary to consider the repository as a wrapper over EF.
Now a couple of notes:
like this
public IEnumerable<Student> GetLogs()
{
return context.Logs;
}
In principle, the post above answered, but I will also add.
If you close ToList() for each request, then indeed, for each such action there will be a request to the database. If you use LINQ, even if there are several lines of code, one query to the database will be generated. And repositories are often wrapped in one service, centralized access to data and work already with it.
Users.Find(id).Logs.Where(x => x.Date == date) or
Logs.Where(x => x.UserId == userId && x.Date == date)
Either way there will be one request.
And for each complex request (often requested), a method is added to the interface.
It is necessary, it is not necessary, this is a personal matter if only one person is involved in the project. If it needs to be supported, developed, then you have to think about flexibility. And they don’t always change the provider, they can go to pure ado.net if the orm stops pulling some requests. Therefore, without a repository, it is problematic here.
1. Write your own methods to infinity (There won’t be many such methods)
2. Also write your own method, place it depending on which table the selection is from (In your case, logs)
3. Connect 1 if you need 15 , then connect 15 one by one, but here you most likely have a clear violation of the single responsibility principle. There should be no problems, there are IoC containers, a facade, if necessary.
4. Lazy loading is used only where performance is not critical, in all other cases it is disabled and all data is received at once
5. This pattern is primarily used to eliminate code duplication and encapsulation, which is the basis of OOP. If you need a "clean" and flexible code, there is nothing difficult to implement and maintain a repository, this is a very simple pattern, and if it seems complicated to you, then you did not understand it.
Didn't find what you were looking for?
Ask your questionAsk a Question
731 491 924 answers to any question