devermind.com
Adrian Grigore’s software development weblog. Motto: I will not waste my time looking for a clever motto.
  • Home
  • About
  • Contact me
  • Privacy Policy

Updated: Generic base class for LINQ2SQL data layers

LINQ Add comments

Hi,

It’s been a while since I posted the first version of my generic base class for LINQ2SQL data layers. The idea behind this class was to provide a quick and simple way to implement a repository with LINQ2SQL and therefore also a solid foundation for implementing your n-tier architecture data layer. If you missed the article, you can read more about the base class here.

The version I previously posted has worked fine for me, but it was still lacking a way to retrieve the ID and version attributes of saved entities. Due to a typo, it also did not work with entities that have more than one unique identity column. Thanks to Mike and Fabrizio for pointing out these limitations!

Version 0.2 available here fixes both of these issues:

Download RepositoryBase Demo Website

Download RepositoryBase Source Code Only

Tags: ASP.NET, CSharp, DAL, LINQ, multi-tier


February 26th, 2009 |

Tags: ASP.NET, CSharp, DAL, LINQ, multi-tier


30 Responses to “Updated: Generic base class for LINQ2SQL data layers”

  1. A generic base class for LINQ to SQL Data Layers | devermind.com
    February 26th, 2009 at 4:30 pm

    [...] http://devermind.com/uncategorized/updated-generic-base-class-for-linq2sql-data-layers [...]


  2. Jerry Nixon
    March 26th, 2009 at 5:46 am

    Holy smack, you got it. Nice.


  3. roping.zong
    March 30th, 2009 at 2:29 pm

    I from kunshan of china.Thanks for your greate job. how a graceful solution for n-tier architecture data layer by LINQ2SQL .Certainly it is. I don’t think I’ve ever seen a better design.


  4. Rob Lloyd
    April 2nd, 2009 at 6:36 pm

    Hi,
    I have just got hold of your code and I have had to fiddle around with it as we do not have int ID fields for our tables but have Guids (please don’t ask, I didn’t design it and no we don’t need keys that are unique across the database…). I have only flicked thorugh it but wondered if you could quickly tell me if this is likely to cause problems. Especially with saving recursively and the is new method.
    Hope that makes sense.
    Thanks for the great artcile
    Rob


  5. Adrian Grigore
    April 2nd, 2009 at 10:08 pm

    Hi Rob,

    Thanks for your interest in my article.

    I must admit I have never used GUIDs, so I can only guess. I think you should be able to alter RepositoryBase to fit your needs. A few points that come to my mind:

    * As you correctly observed, the Save() / SaveRecursively() methods use the ID attribute to find out whether the business entity is new to the database. Basically you should be able to do this in a similar manner with a GUID, as long as newly constructed entities always have one well-defined GUID that never occurs in entities that have been loaded from the database.

    * Repositorybase finds the ID property of each business entity automatically (even if it is not called “ID”) by reflecting on the respective table ( see lines 196, 331 and 385 of RepositoryBase). You’ll need to use an alternate mechanism for finding the GUID property instead. The simplest option would be to call your GUID properties “GUID” or something similar in all business entity types and to hardcode that property name in RepositoryBase. This will also remove a bit of reflection.

    * You will also have to alter the Load() and Delete methods in RepositoryBase as well as GetIDSelector() from the business entities to use GUIDs, but that should be trivial.

    Please let me know if it worked. And if you have a blog, a pingback is always appreciated ;-)

    Good luck,

    Adrian


  6. Rob Lloyd
    April 3rd, 2009 at 9:49 am

    Hi Adrian,
    Thanks for a a quick a thorough response!

    Looks like I may have more problems as there are quite a lot of many to many relationships which have multiple value keys that vary. I will try and come up with a nice solution using a repository, though looks like I may have to try and do it in my own time and use a dirty solution for the deadline I am on :-( . If I come up with anything I’ll try and document it somewhere and let you know.

    Thanks again
    Rob


  7. Gary
    April 23rd, 2009 at 3:36 pm

    Does this work with composite primary keys? I talking about a link table like OrderDetails that might have the OrderID and ProductID as the primary key.

    Thanks
    Gaz


  8. Adrian Grigore
    April 24th, 2009 at 10:43 am

    Gary,

    This does not work out of the box with composite primary keys. However, it should be quite easy to adapt it accordingly.

    The Load(int ID) and Delete(int ID) and DeleteRecursively(int ID) functions will have to be changed to accept two parameters, but that’s trivial since Load is just filtering the respective table and the real work in Delete is done in Internal functions that take in an entity (not an ID) anyway. The rest might work with composite primary keys without further changes, although I have not tried it yet.


  9. Chris Pisani
    May 16th, 2009 at 7:49 pm

    Adrian,

    Where in the updated BaseRepository are the child IDs set for the SaveRecursively functionality?

    Thanks,
    Chris


  10. Adrian Grigore
    May 18th, 2009 at 5:08 pm

    @Chris: This should be done automatically by the LINQ2SQL data context. Setting the ID and version attributes explicitly is only necessary for the root entity, because this is the only entity that is being detached from any previous context by serializing it. For some obscure reason explicitly detaching the child entities does not seem to be necessary, so the RepositoryBase does not do it.


  11. Mark Kamoski
    July 10th, 2009 at 9:37 pm

    FYI, when I try to run the out-of-the-box sample, I get the following RTE on start “ObjectDataSource ‘BillsListObjectDataSource’ could not find a non-generic method ‘LoadAll’ that has parameters: ID”. This is, if I recall correctly, an issue with the ObjectDataSource in DotNet, I think and it is fixable BUT I thought you should know anyway. Thank you regardless because the code is quite underneath, IMHO. Thank you. — Mark Kamoski


  12. Mark Kamoski
    July 14th, 2009 at 10:45 pm

    FYI, I tweaked your sample’s UI a bit to get it working. (The backend code seems fine.) I had to remove the selectparameters for bills BillsListObjectDataSource and BillingItemsDataSource and change both to selectmethod=”LoadAll” because they underlying objects did not seem to have “select where some_id = some_selected_id” (or at least I could not get it to work). If you want the tweaked sample, then please just send a request to mkamoski@yahoo.com because I do not see a way to email it to you directly. Anyway, this seems fine so far. I appreciate the help. Thank you. — Mark Kamoski


  13. Adrian Grigore
    July 15th, 2009 at 6:35 pm

    @Mark: See the e-mails I have sent you regarding this.


  14. Gboyega S
    October 29th, 2009 at 3:58 pm

    Hi Adrian,

    Attempting to save an item after edit gives this error

    “An entity can only be attached as modified without original state if it declares a version member or does not have an update check policy.”

    How can one get around this, given that the detaching and serialising would have gotten rid of the original state.

    Thanks.


  15. Adrian Grigore
    October 29th, 2009 at 4:33 pm

    @Gboyega S : Sounds like your table does not have a version column. See the demo website for an example of a table with version information.


  16. camilla
    November 13th, 2009 at 10:53 pm

    Hi, I’m working on a new project and using LINQ. New to it. Why do I need to use a base class? as I have it now, I have a DBML. I drag my tables and my stored procs to it and call the stored procs or use tables (entities). Not sure if this is a correct design…


  17. Roger
    December 16th, 2009 at 4:53 pm

    Hi Adrian,
    I am trying to implement your repositorybase in an asp.net mvc project.
    My database table (sql2005, not express) has a version column. I created the table using a sql script and used rowversion instead of timestamp as datatype.
    Still the output window in visual studio keeps telling me that there is no version on the linq entity.
    Inserting a new row is possible, updating an existing row not.

    What is going wrong here?
    Many thanks in advance.
    roger


  18. Roger
    December 16th, 2009 at 4:54 pm

    Oops, forgot to include mailaddress.


  19. Adrian Grigore
    December 16th, 2009 at 6:46 pm

    Roger,

    Where does the error message come from? Is it Linq or my RepositoryBase class?


  20. Roger
    December 16th, 2009 at 9:05 pm

    Hi Adrian,

    I just send you an email with a detailed explanation.
    In short the error is:
    Warning: “StaticText” entity type does not have a version property. You might want to add a version column to speed up Saving and Deleting of “StaticText” entities.

    The column is in the table.


  21. Khayralla
    December 31st, 2009 at 6:51 am

    Hi Adrian,

    I would like to implement your repositorybase in a multithreaded Desktop application.
    Do you think it is possible to implement it ?

    Is there any seggestions ?

    Thanks


  22. Adrian Grigore
    December 31st, 2009 at 11:37 am

    @Kayralla: It’s certainly possible. The repository’s implementation does not depend on the UI plattform you are using. You can use it with ASP.NET just as well as with a desktop UI.


  23. Khayralla
    December 31st, 2009 at 6:56 pm

    thanks for the fast replay.

    One of the tables in my database contain 4 primary keys. (Guid, int, int, int)
    How can I implement that in :
    protected abstract Expression<Func> GetIDSelector(TIDType ID);

    thanks again


  24. Khayralla
    December 31st, 2009 at 9:25 pm

    Hi Adrian

    It is done.
    thanks for this nice article

    Khayralla


  25. Mike
    February 24th, 2010 at 3:23 pm

    I can’t get the demo to work. I load the website and receive the below error.

    ObjectDataSource ‘BillsListObjectDataSource’ could not find a non-generic method ‘LoadAll’ that has parameters: ID.


  26. Adrian Grigore
    February 26th, 2010 at 9:30 am

    What VS version are you using?


  27. NoiK
    April 7th, 2010 at 10:11 am

    Hey,

    I’ve tried implementing your repository with an manually mapped class, well actually multiple classes.
    The Load and the Save function seem to work fine, no problem at all.

    Only the update function is giving me problems. It is giving me errors on the attach function. I know this is not related to the repository but to the datacontext but have you ever seen this before with an other user?
    I must say i have removed the HasVersion(Property) function.

    TIA


  28. Adrian Grigore
    April 7th, 2010 at 10:27 am

    Hi NoiK,

    Sorry, but I have not been using disconnected linq for about 1 year now (thanks to coding in ASP.NET MVC), so am not fully accustomed with the code anymore. Without knowing any more details, I’m afraid I can’t you help here…


  29. NoiK
    April 7th, 2010 at 10:31 am

    You mean you’re missing details from my side? Or because you were not in L2S for a while?

    Thanks anyway :)


  30. Adrian Grigore
    April 7th, 2010 at 11:10 am

    Both. I would at least need to know the specific error message. But even with that, I am not sure if I could point you in the right direction without debugging your (and my) code. As I said, nowadays I am not using disconnected Linq anymore.


  • Feeds

    • RSS feed iconAll Entries
    • RSS feed iconAll Comments
    • RSS feed iconThis Post's Comments
  • About Adrian Grigore

    Adrian Grigore Adrian is a software developer from Fulda, Germany. Adrian has been programming C++ applications since 1998. Recently he has been implementing a Web 2.0 SaaS website, so his current development-related interests are ASP.NET MVC, C#, and jQuery.


  • Adrian's (German language) book

    XSLT XUpdate BuchXUpdate mittels XSLT - Ein XUpdate-Prozessor auf XSLT-Basis


  • Pages

    • About
    • Contact me
    • Privacy Policy
  • Links

    • Lobstersoft
    • SonicWeasel
  • Tags

    ASP.NET ASP.NET MVC binding Business client-side form validation client-side validation codedui selenium testing test CSharp custom DAL dataannotationsmodelbinder form validation games guide jQuery jQuery.validate LINQ MSBuild multi-tier mvc POST remote validation shareware tutorial viewmodel visual-studio asp.net xVal
  • Archive

    • May 2010 (2)
    • January 2010 (2)
    • June 2009 (1)
    • May 2009 (1)
    • April 2009 (1)
    • March 2009 (2)
    • February 2009 (1)
    • October 2008 (2)
Copyright © 2010 devermind.com All Rights Reserved
RSS XHTML CSS Log in
Wp Theme by n Graphic Design
Powered by Wordpress