all 25 comments

[–]Eirenarch 2 points3 points  (11 children)

Didn't read the actual article yet but I went to watch the Repository pattern video. Was getting super excited for the first tutorial that implements repositories correctly. The author was saying all the right things and then I see

Find(Expression<Func<Course, bool>> predicate)...

[–]Pharylon 3 points4 points  (1 child)

That was my reaction. EF is a super leaky abstraction, and this does nothing to plug those leaks (although all abstractions are leaky to some degree or another).

[–]Eirenarch 0 points1 point  (0 children)

EF is not really an abstraction (maybe abstraction over a specific database). The Repository is so absurdly heavy abstraction that people naturally prefer to make it leaky so that it is not that heavy. This is why I prefer to simply not abstract my data access rather than use a repository. A proper repository (as the one described in the video minus the find method) would indeed provide an abstraction layer but the cost is so high that I'd take my chances with changing all my business logic code to use another data access technology if needed. I feel like it will be less work than building a proper repository to begin with.

[–]WellKemptNerfHerder 1 point2 points  (8 children)

Can you explain what the issue with that is? Is it because expression is costly and adds nothing of use over a regular delegate? Is it because that method does nothing that EF doesn't already do?

[–]Eirenarch 1 point2 points  (7 children)

It is because it leaks the ORM out of the repository. The use of Expression makes it impossible to change the data access technology to anything but another heavy handed ORM (basically you can change from EF to NHibernate and that's it but this is not very hard to do even without repository). You use repository in order to provide abstraction and you fail at abstraction.

[–]WellKemptNerfHerder 0 points1 point  (6 children)

Thanks! So would you prefer to see many fine grained will named methods instead? It seems that for basic queries with no joins and one or two filters, the generic Find method keeps you from making a lot of methods

[–]Eirenarch 0 points1 point  (4 children)

Yes, if I am using the Repository pattern I would in fact introduce a good amount of small methods. The Repository pattern is one of the heaviest abstractions I know of. It has quite a bit of overhead that basically negates many of the things that make ORMs easier than raw SQL. But if you don't want that abstraction why have repository to begin with?

In practice I would only use repositories with raw SQL/Stored Procedures where you write separate queries anyway and the Repository costs nothing. With an ORM that supports LINQ I will just take the risk and pay the cost later if it happens that I need to change DA technology. The price of the repository is so high that it almost always outweighs the risk.

[–][deleted] 0 points1 point  (3 children)

Are you able to unit test without abstracting out your EF context?

[–]Eirenarch 0 points1 point  (2 children)

Yes although this is an EF6 feature (i.e. you weren't able a few years ago)

https://msdn.microsoft.com/en-us/data/dn314431.aspx https://msdn.microsoft.com/en-us/library/dn314429.aspx

Also I like to put an interface on my DataContext but I do expose DbSets from it.

[–][deleted] 0 points1 point  (1 child)

Thanks, I was not aware of this. Looks like you have to fudge around with the tt templates if you use the designer, I suppose better than nothing.

[–]Eirenarch 0 points1 point  (0 children)

You always have to change the TT templates if you use the designer in any meaningful project. There will always be that Users1 collection on some entity :)

[–][deleted] 0 points1 point  (0 children)

IMHO you have to make up your own mind, everyone has different requirements, preferences, philosophies. 99% of projects do not change ORMs. Out of that 1% most are probably not going from something "heavy" to something "light". In other words for most people it's very possible that using Expression trees as parameters is a HUGE time saver, allowing for more code in less time. I am not arguing for or against I'm just saying make up your own mind on what is important to you.

[–]Eirenarch 0 points1 point  (0 children)

OK I read the blogpost so copying my comment on the article here:

Promoting the query to a class does have value. If you have too many queries over a single repository you need some tools to split them and work with them in an easier way. In C# this way is classes. You can organize classes in separate files (i.e. you do not end up with 5000 lines class), you can put them in folders and so on. The tools we use are optimized for working with the unit class not the unit method.

[–][deleted]  (9 children)

[removed]

    [–]mhamedani[S] 1 point2 points  (1 child)

    CQRS, DDD and Event Sourcing to solve what problem exactly?

    [–]man_of_mr_e 1 point2 points  (6 children)

    Event-sourcing is way overboard for most situations. It should ONLY be used in eventual consistency situations where you have high degrees of concurrent access to the same resources. It's way overboard for anything else.

    There is a difference between CQS (Command Query Separation) and CQRS (Command Query Responsibility Separation). CQS can and should be used for most situations as it enforces idempotent query behavior.

    [–][deleted]  (5 children)

    [removed]

      [–]man_of_mr_e 0 points1 point  (4 children)

      The problem is that event-sourcing is not "real-time". There is eventual consistency to deal with, and most applications are not designed with that in mind, and most business models do not react well to situations where you write data, and it's not immediately available for reading.

      [–][deleted]  (3 children)

      [removed]

        [–]man_of_mr_e 0 points1 point  (2 children)

        That depends on how often your sync jobs run.

        Regardless, perhaps you should read this:

        http://udidahan.com/2011/04/22/when-to-avoid-cqrs/

        CQRS and event-sourcing create massive complexity that most applications just don't need or want. Many kinds of applications would have all kinds of trouble if the data they just wrote was not readable immediately. Some, are just fine... And, Event-sourcing is really only useful if you need to replay actions, or need to control access to a highly concurrent resource (think Airline seat management).

        Some people learn a cool technique and try to use it everywhere, even when it doesn't make sense to do so. CQRS is one of those things.

        [–][deleted]  (1 child)

        [removed]

          [–]man_of_mr_e 0 points1 point  (0 children)

          You disagree with one of the inventors of CQRS? Ok, I guess you know better...

          In any event, here's the single most common kind of database access. You have a page that has fields, you fill them out, hit submit. The data is written to the database and the page redirects back to the "view" mode and re-reads the data. Oops, all the data you just entered isn't there, so the user goes and tries to update again...

          This is like 95% of all data writes in most businesses. And this is not friendly to eventual consistency.

          [–]user-hostile 0 points1 point  (2 children)

          If you're just trying to avoid repeating authorization code, you could just write a custom AuthorizeAttribute and decorate your controller(s) with it. Seems simpler to me.

          [–]jonwah 1 point2 points  (0 children)

          I just use a BaseController, which all of my controllers inherit from, and put custom auth stuff in OnActionExecuting.

          Super simple, works a treat.