How can I write a clean Repository without exposing IQueryable to the rest of my application?

后端 未结 5 1672
时光取名叫无心
时光取名叫无心 2021-01-31 05:26

So, I\'ve read all the Q&A\'s here on SO regarding the subject of whether or not to expose IQueryable to the rest of your project or not (see here, and here), and I\'ve ulti

5条回答
  •  半阙折子戏
    2021-01-31 06:06

    Exposing an IQueryable is a very viable solution and this is how most of the Repository implementations out there doing right now. (Including SharpArchitecture and FubuMVC contrib, as well.)

    This is where you are wrong:

    However, if you aren't using IQueryable then methods like GetAll() aren't really practical since lazy evaluation won't be taking place down the line. I don't want to return 10,000 records only to use 10 of them later.

    This is not realy true. Your example is correct and you should rename GetAll() to a more informative name.

    It DOESN'T return all of the items if you call it. That is what IQueryable is for. The concept is called "deferred loading", as it only loads the data (and makes database requests) when you enumerate the IQueryable.

    So, let's say I have a method like this:

    IQueryable Retrieve() { ... }
    

    Then, I can call it like this:

    Repository.Retrieve().Single(c => c.ID == myID);
    

    This ONLY retrieves one row from the database.

    And this:

    Repository.Retrieve().Where(c => c.FirstName == "Joe").OrderBy(c => c.LastName);
    

    This also generates a corresponding query and is only executed when you enumerate it. (It generates an expression tree from the query, and then the query provider should translate that into an appropriate query against the data source.)

    You can read more about it in this MSDN article.

提交回复
热议问题