Entity Framework Talk at Atlanta Code Camp 2013

As you have noticed from my previous posts, Atlanta Code Camp took place yesterday, August 24th.  I spoke on Entity Framework, and wanted to post my slides and a sample project.  Here is the session description.

Entity Framework Code First End to End

This session will cover the use Entity Framework in .NET based applications. Discussion will include model creation and organization as well as schema evolution via migrations. The role of data annotations in Entity Framework model creation and validation will be highlighted. Key issues in achieving performance will be part of the talk, including ability to embed stored procedures when necessary. Creation of a maintainable data access layer via use of repositories will be illustrated. An ASP.NET MVC application will be built throughout the talk to illustrate the concepts.

 

Here are the links:

Thank you!

27 Comments

  1. Great talk.
    I noticed you mentioned batch updates briely in your talk. In my app the user will work on multiple objects (adding deleting and updating) before saving. It looks like in your code you need to have the context around during that time until you savechanges. Any thoughts on that? It seems to be a general challenge with EF 5 though that might be addressed post EF 6.

  2. Thanks, Martin.
    Yes, if you want to group updates into a single transaction, you have to do those updates with the same instance of DbContext. If you use generic repository that can update any type of record, you can use the same repository for all the updates though. Is this an issue for you?
    Also, you could use different contexts within TransactionScope, but you will need to have MSDTC running, which is not ideal. I hope this helps, unless I am missing something.

  3. I was not talking about shared context, but an instance specific to your unit of work that you use to update all the data in this unit. You do not need to keep it around passed the final SaveChanges either. Maybe if you provide and example, it would be more clear.

    • At the moment my DBContext is my unit of work (behind an IContext interface). I’m keeping the context around until savechanges.

      Something like this:

      interface IContext: IDisposable
      {
      int SaveChanges();
      TItem AddItem();
      void DeleteItem(TItem item);
      IEnumerable GetAllItems();
      }

      In a seperate project
      public class Context: DBContext, IContext
      {
      // Implementation
      }

      Calling Code:
      var ctx = IoC.Get(); // create a Context here
      // Add, Delete or Modify Items tracked by ctx
      // until user presses save project
      ctx.SaveChanges();

      I’d like to start with a fresh context, but just calling
      ctx.Dispose(); won’t do it. Need a way to re-attach or perhaps i can just hang on to the context (but that seem to go against best practices)

    • I want to do the same for the desktop app. The problems occurs for me when disposing the context. The proxies stay around but all the states are set to unchanged and graph relationships are lost (http://stackoverflow.com/questions/3635071/update-relationships-when-saving-changes-of-ef4-poco-objects/3635326#3635326).
      so if i do the following in the code above

      ctx.SaveChanges();
      ctx.Dispose();
      ctx = IoC.Get(); // resolve new DBContext
      ReAttachGrapToContext();

      All the proxies will have a state of unchanged (not a problem in this case since i just saved), but the graph relationships in the proxies are lost as well.

      Looking at your code, a new context is created when you create a WriteRepository and disposed when you dispose the repository. It does however not seem to take the state changes of the proxies into account.
      If you insert a Contact for example (EntityState.Added) and then dispose the repository (EntityState back to unchanged!). Then try to save the contact with a new repository it will not save

    • 1 New up a write repository
      2 Update an item (state = EntityState.Modified)
      3 Dispose repository((state = EntityState.Unchanged triggered by disposing of DbContext)

      4 New up a write repository
      5 SaveChanges (nothing gets saved eventhough the proxy still has the changes)

      Hence you are forced to savechanges before the dispose or manually set the state back to EntityState.Modified and then SaveChanges

  4. I think you are describing the normal web app flow. On post back new up repo, attach items, marked as modified, save, dispose repo. I think the issue you are experiencing is that you want the repo to hang around for you, but I am not sure why. Usually I just get the data and dispose repo. When I am ready to save, I do all the work right away, as I describe above in this answer.

  5. In our apps we check for changes in the web site and save when items change. We do not currently track each item, but we could. I think you are speaking to the fact that you are using EF objects as business objects, and you can, but you have to make them smarter so that they know what state they are in. If you have business objects on top of EF classes, you can put those smarts in business objects. Hence, the reason I advocate using EF as DAL only. My 2 cents.

    • I think you hit the nail with the hammer. I’ve been sceptical of using a seperate model for the business objects. It seems that EF code first is so close to be used for the business layer, but when it comes down to it it’s missing a few things. Hopefully they will be adressed post EF6 or perhaps you can help me in the right direction. Could it be as simple as introducing a property in the business object to keep track of the state?

      I might still go the route of using a second model for the business layer.
      You’re talk convinced me that it’s not too complicated. I’m also thinking of using CSLA objects for the business layer and your approach would fit nicely. Then using the state tracking build into CSLA objects, EF state tracking should be a non issue.
      Thanks for your input.

  6. Thank you SIr, great explanation
    I’ve one question, what if I’ve a DateTime property in one of my tables, how to set it to .UtcNow() from c# code (configuration class)

    for now I’m using a contractor to initialize it :

    public class Video
    {
    public Video()
    {
    Date = DateTime.UtcNow;
    }

    public int VideoId { get; set; }

    public string VideoTitle { get; set; }

    public string VideoUrl { get; set; }

    public DateTime Date { get; set; }

    public string Description { get; set; }
    }

  7. @Med,
    Oh, I see. No, I never had a need to do this because I would consider this business logic, so it would reside in a business object, not an EF DTO. If you are using EF POCOs directly in the UI, then this is correct location for your code I think, assuming you are populating this for new Videos.
    Hope this helps.

  8. Thank you Sir for your help,

    I was trying to do the same as you did in the video, but I can’t understand what inside of business project (mapping…)

    Can you please give some links or tutorials to better understand this architecture

    And thank you again for helping people

  9. I do not think I have anything beyond the video on you tube for the talk. The idea is that you create a set of objects you expose to UI, and just map those objects to EF classes for persistence.

  10. Hello Sergey!

    Thanks for that video and sample. I am new to EF so i found your code very handy. But I am having some issues with relationships. For example, when I want to save a Signature object with a FK to Document object (and Document Object has a FK to Company object).

    Basically when I want to save a set of Signatures, EF triggers validation for Document and Company. Even thou I am passing an id to DocumentID in Signature object.

    What am i doing wrong?

    Jose

Leave a Reply to Sergey Barskiy Cancel reply

Your email address will not be published. Required fields are marked *