Programming Entity Framework

Julia Lerman, Rowan Miller

Mentioned 14

Shows how to perform set operations with the DbSet class, control change tracking, fix concurrency conflicts, and confirm changes made to data.

More on Amazon.com

Mentioned in questions and answers.

I have been working with Entity Framework 4 recently, and am slightly confused as to when to use ObjectSet.Attach, and ObjectSet.AddObject.

From my understanding:

  • Use "Attach" when an Entity already exists in the system
  • Use "AddObject" when creating a brand new Entity

So, if i'm creating a new Person, i do this.

var ctx = new MyEntities();
var newPerson = new Person { Name = "Joe Bloggs" };
ctx.Persons.AddObject(newPerson);
ctx.SaveChanges();

If i'm modifying an existing Person, i do this:

var ctx = new MyEntities();
var existingPerson = ctx.Persons.SingleOrDefault(p => p.Name = "Joe Bloggs" };
existingPerson.Name = "Joe Briggs";
ctx.SaveChanges();

Keep in mind, this is a very simple example. In reality i am using Pure POCO's (no code generation), Repository pattern (don't deal with ctx.Persons), and Unit of Work (don't deal with ctx.SaveChanges). But "under the covers", the above is what happens in my implementation.

Now, my question - I am yet to find a scenario where i have had to use Attach.

What am i missing here? When do we need to use Attach?

EDIT

Just to clarify, i'm looking for examples of when to use Attach over AddObject (or vice-versa).

EDIT 2

The below answer is correct (which i accepted), but thought i'd add another example where Attach would be useful.

In my above example for modifying an existing Person, two queries are actually being executed.

One to retrieve the Person (.SingleOrDefault), and another to perform the UPDATE (.SaveChanges).

If (for some reason), i already knew that "Joe Bloggs" existed in the system, why do an extra query to get him first? I could do this:

var ctx = new MyEntities();
var existingPerson = new Person { Name = "Joe Bloggs" };
ctx.Persons.Attach(existingPerson);
ctx.SaveChanges();

This will result in just an UPDATE statement being executed.

This is a quote from Programming Entity Framework: DbContext

Calling Remove on an entity that isn’t tracked by the context will cause an InvalidOperationException to be thrown. The Entity Framework throws this exception because it isn’t clear whether the entity you are trying to remove is an existing entity that should be marked for deletion or a new entity that should just be ignored. For this reason, we can’t use just Remove to mark a disconnected entity as Deleted; we need to Attach it first.

private static void TestDeleteDestination()
{
    Destination canyon;
    using (var context = new BreakAwayContext())
    {
        canyon = (from d in context.Destinations
        where d.Name == "Grand Canyon"
        select d).Single();
    }
    DeleteDestination(canyon);
}
private static void DeleteDestination(Destination destination)
{
    using (var context = new BreakAwayContext())
    {
        context.Destinations.Attach(destination);
        context.Destinations.Remove(destination);
        context.SaveChanges();
    }
}

The TestDeleteDestination method simulates a client application fetching an existing Destination from the server and then passing it to the DeleteDestination method on the server. The DeleteDestination method uses the Attach method to let the context know that it’s an existing Destination. Then the Remove method is used to register the existing Destination for deletion

I just downloaded EntityFramework.dll v4.3, I found a lot of questions about DbContext vs ObjectContext but most of these are from 2010, or early 2011. I wanted to read more on the subject, specifically are there any books on DbContext I can get my hands on? I also wanted to know, as of today, what are the limitations of DbContext when comparing it to it's older brother the ObjectContext. I realize DbContext is more compact in that it exposes fewer properties, which allures me to migrate from ObjectContext. But I've read for example that DbContext doesn't have the STE (Self-tracking entities) capability; does this still hold true?

I wanted to read more on the subject, specifically are there any books on DbContext I can get my hands on?

It is not very good beginning of your question because single google query will give you answer for this. There is an excelent book about DbContext itself - it doesn't contain anything about code first approach but I guess it is not point of your question.

I found a lot of questions about DbContext vs ObjectContext but most of these are from 2010, or early 2011

If you want just replace ObjectContext + EDMX with DbContext + EDMX the comparison is still the same. DbContext is wrapper around ObjectContext and its feature set didn't grow up except features related to code first and migrations.

I realize DbContext is more compact in that it exposes less properties, which allures me to migrate from ObjectContext.

Yes it is more compact and it simplifies most common tasks you have to do with the context. For more complex tasks you can still convert DbContext instance to ObjectContext instace through IObjectContextAdapter.

But I've read for example that DbContext doesn't have the STE (Self-tracking entities) capability; does this still hold true?

It was created for ObjectContext and I don't think it was ported to DbContext but you can try to make it yourselves.

STEs are just a template with idea to solve some problem. It appeared as a good theoretical solution but it wasn't very well accepted by the developers community because the solution is not very good for the real world scenarios. It is also reason why other more important features are developed instead of improving or porting the template.

My Order class has:

public int CustomerId { get; set; }

public Customer Customer { get; set; }

Do I really need both properties to make a relation working?

I am not using disconnected entities, I am using code first approach.

According to Julia Lerman's book: Programming Entity Framework: DbContext, the difference lies at the difficulty of updating the navigation property. In page 85, She suggests "If there is one thing you can do to make your life easier in N-Tier scenarios, it’s to expose foreign key properties for the relationships in your model." The book includes samples for both scenarios.

The reason is that including a foreign key property tells Entity Framework to use Foreign Key Association, which is simpler than using the so-called Independent Association when you need to update the relationship, i.e., changing the order from one customer to another in your example. With foreign key association, all you need to do is changing the CustomerId. Without the CustomerId foreign key, you need more steps. The independent association uses the ObjectStateManager that is explained Code First: Independent associations vs. Foreign key associations? The ObjectStateManager is complex and is not even exposed from DbContext API.

I am making an MVC4 web application using Entity Framework 5 (Database-first with generated POCOs) for data access.

In the app, the user goes through several screens, creating or editing a document (called a 'case study'). When they arrive at the final screen, their document exists as a CaseStudy POCO in memory, and everything is great until it is time to save this structure to the database.

To store the document, I have defined several database tables, which in turn map to EF POCOs used by the business layer, which is then consumed by the MVC controllers. As such, short-lived DbContexts are used to retrieve POCOs and store them in session between requests.

As a result, the save screen must save the contents of this POCO that has navigational properties to existing table data (Category, Layout, and Sections tables), and also added or updated data (CaseStudySections and the CaseStudy itself). So all of the POCOs are either new, or the context used to retrieve them has long been disposed. In other words, they are all 'detached'.

What is unusual about this post is that I already have a working solution in hand. The problem is that it is bulky, brittle, and inelegant. I am posting the code below. Note the iteration through sub-collections, the explicit adds and attaches, having to get an entry object and mark individual properties as modified just so they will be updated, and the awful song and dance at the end to get the AdditionalMaterials collection synced up. If this is what is required to deal with detached POCOs in EF5 I will be disappointed.

Am I missing something here? Is this consistent with best practices? Is there a more graceful and/or concise way to attach a structure of POCOs and insert/update?

The code to save a case study:

public void SaveCaseStudy(CaseStudy caseStudy)
{
    foreach (var s in caseStudy.CaseStudySections)
    {
        this.Entities.Sections.Attach(s.Section);

        if (s.CreatedByRefId == default(Guid))
        {
            s.CreatedByRefId = this.UserRefId;
            s.CreatedTime = DateTime.Now;
            this.Entities.CaseStudySections.Add(s);
        }
        else
        {
            this.Entities.CaseStudySections.Attach(s);
            var entry = this.Entities.Entry(s);
            entry.Property(e => e.TextData).IsModified = true;
            entry.Property(e => e.BinaryData).IsModified = true;
        }

        s.LastModifiedByRefId = this.UserRefId;
        s.LastModifiedTime = DateTime.Now;
    }

    foreach (var m in caseStudy.AdditionalMaterials)
    {
        if (m.CreatedByRefId == default(Guid))
        {
            m.CreatedByRefId = this.UserRefId;
            m.CreatedTime = DateTime.Now;
            this.Entities.AdditionalMaterials.Add(m);
        }
        else
        {
            this.Entities.AdditionalMaterials.Attach(m);
        }

        m.LastModifiedByRefId = this.UserRefId;
        m.LastModifiedByTime = DateTime.Now;
    }

    this.Entities.Layouts.Attach(caseStudy.Layout);
    this.Entities.Categories.Attach(caseStudy.Category);

    if (caseStudy.CreatedByRefId != default(Guid))
    {
        this.Entities.CaseStudies.Attach(caseStudy);
        var entry = this.Entities.Entry(caseStudy);
        entry.Property(e => e.CaseStudyName).IsModified = true;
        entry.Property(e => e.CaseStudyTitle).IsModified = true;
    }
    else
    {
        this.Entities.CaseStudies.Add(caseStudy);
        caseStudy.CreatedByRefId = this.UserRefId;
        caseStudy.CreatedTime = DateTime.Now;
    }

    caseStudy.LastModifiedByRefId = this.UserRefId;
    caseStudy.LastModifiedTime = DateTime.Now;

    if (caseStudy.CaseStudyStatus != (int)CaseStudyStatus.Personalized)
    {
        caseStudy.CaseStudyStatus = (int)CaseStudyStatus.PendingApproval;
    }

    caseStudy.ApprovedByRefId = null;
    caseStudy.ApprovedTime = null;
    this.Entities.SaveChanges();

    var existingAdditionalMaterialRefIds = caseStudy.AdditionalMaterials
        .Select(m => m.AdditionalMaterialRefId)
        .ToArray();

    var additionalMaterialsToRemove = this.Entities.AdditionalMaterials
        .Where(m => 
            m.CaseStudyRefId == caseStudy.CaseStudyRefId && 
            !existingAdditionalMaterialRefIds.Contains(m.AdditionalMaterialRefId))
        .ToArray();

    foreach (var additionalMaterialToRemove in additionalMaterialsToRemove)
    {
        this.Entities.AdditionalMaterials.Remove(additionalMaterialToRemove);
    }

    this.Entities.SaveChanges();
}

In general it is what you have to do. You must tell EF about each change you want to perform when attaching detached object graph. I don't say that your code cannot be simplified but you will still have to deal with every entity and setting its state if you want it to be added or modified.

Here is little bit older but still valid answer about the topic - in short nothing has changes since I wrote it, only new DbContext API was created which still sits on top of the old API. The best description of this topic I have seen so far is in book Programming Entity Framework: DbContext.

First of all: I'm an EF-newbie, and this is just to test the capabilities of EF, and to see how it fits into an environment which is already set in terms of database tables and object model - and when these two models do not map 1:1 in terms of class names/table names and attribute names/column names, and even the number of tables and classes. Please keep "test the capabilities" in mind should you feel the urge to reply: "EF is not meant to be used that way". Thanks! :)

Consider the following scenario.

I have three database tables:

|----------------|       |-------------|       |-----------------|
|   MessageLog   | >---1 |   Message   | 1---< |   MessageText   |
|----------------|       |-------------|       |-----------------|
| logId          |       | messageId   |       | messageId       |
| messageId      |       | type        |       | languageCode    |
| from           |       | ...         |       | text1           |
| to             |       |-------------|       | text2           |
| ...            |                             | ...             |
|----------------|                             |-----------------|

Which I want to map to two classes:

|--------------------|       |----------------------------|
|   ServiceMessage   |<-\    |   ServiceMessageInstance   |
|--------------------|  |    |----------------------------|
| Id: string         |  |    | Id: string                 |
| LanguageCode: str. |  \----| Message: ServiceMessage    |
| Text1: string      |       | From: DateTime             |
| Text2: string      |       | To: DateTime               |
| Type: MessageType  |       |----------------------------|
|--------------------|

ServiceMessage objects are comprised of a row from the Message table (with messageId as key) and a row from the MessageText table (with messageId and languageCode as keys).

ServiceMessageInstance is easier: it has a reference to a ServiceMessage object, and some additional attributes.

I have played a bit with EF, and done a lot of googling, but I have not found the answer to my question: How can I make this happen with EF? Which approach should I take? Can I do this with the EDMX designer? DbContext.OnModelCreating?

I realise that this might be a bit too "wide" a question, but I would appreciate any pointers!

Thanks.

BR, Herms

To tell the truth i haven't actually tried to this because i didn't come across a situation that forced me to do so, never the less i remember that when i was reading "Programming Entity Framework DbContext" i came across a section in chapter 5 to be exact called "Mapping a Single Entity Across Multiple Tables" which i think does exactly what you want.
NOTES

  • The above mentioned feature called "Entity Splitting" uses entity framework code first but i assume (not sure) that it is possible with other entity framework mythologies as well.
  • You can't enable it via Data Annotations, instead you will have to configure it with Fluent API.
  • To do that you need to use the Map function.
  • There is also a feature that goes in the other direction too, and it allows you to map multiple entities to a single table.

Is there any good LINQ tutorial for Entities Framework 4.1 Code First for medium to complex level? Please suggest books as well.

For Linq-to-entities you can check MSDN:

Sources for EFv4.1 code first are:

As I know there is no book covering EFv4.1 yet.

Edit (May 2012): There are two books about EFv4.2 (Code first / DbContext API) now:

While searching for the best practivies of performing CRUD operation via EF I noticed that it is highly recommended to use Attach() or Find() methods before updating an entity. It works well and according to EF documentation these methods fetch the entity to context that is quite clear for me. But the followind code confused me pretty much

public void Update(object entity)
{
    Record record = new Record() {
        id = 1,
        value = 5
    };
    using (SomeContext ctx = new SomeContext())
    {
        ctx.Entry(record).State = EntityState.Modified;
        ctx.SaveChanges();
    }
}

Assume we have a record with id = 1 in database. On this condition the code above will update the record (set the value to 5). The question is why it works? And then why should I use Attach()?. As far as I understand the record wasn't attached to context in any way. I read relevant chapters of this book and the tutorial but they use 2-query-approach. Also I surfed SO but didn't find answer on my question. Help me with explanation or some good matherials, please.

If you have an entity that you know already exists in the database but which is not currently being tracked by the context-as your case- then you can tell the context to track the entity using the Attach method on DbSet. So in summary what Attach method do is track the entity in the context and change its state to Unchanged. When you modify some property after that the tracking changes will change its state to Modified for you. In the case you expose above you are telling explicitly that state is Modified but that also attach the entity to your context. You can find a detailed explanation in this post.

When should you use Attach method?

When you have an entity that you know already exists in the database but want to make some changes:

var entity= new Entity{id=1};
context.YourDbSet.Attach(entity); 

// Do some change...  
entity.value=5;

context.SaveChanges(); 

This is the same:

 context.Entry(entity).State = EntityState.Unchanged; 

// Do some change... 
entity.value=5; 

context.SaveChanges(); 

When should you change entity's State to Modified explicitly?

When you have an entity that you know already exists in the database but the changes have already been made then. The same scenario of your example

All,

I purchased The Julia Lerman book Programming DbContext and looking through the examples, I do not see any way to load an existing entity with more than 1 search parameter:

Example from Book:

using (var context = new BreakAwayContext())
{
   var bay = (from d in context.Destinations
              where d.Name =="Wine Glass Bay"
              select d).Single();

   context.Destinations.Remove(bay);
   context.SaveChanges();
}

What if I wanted to find all destinations where d.Name == "Wine Glass Bay" AND d.State = "CA"? I would rather not execute raw SQL if not necessary. Thanks

In C# use the && logical "AND" operator:

from d in context.Destinations
where d.Name  == "Wine Glass Bay" 
   && d.State == "CA"
select d

I have not been able to figure out a good way to search for this - at least not one that worked.

Where can I get information on the best/most appropriate way to implement Entity Framework? I have books, access to this (and other) forums, etc. But the books are rather out of date (even Julia Lerman's 2nd edition EF book) and when I search, I find answers that were correct for an older version, but not the current one. And so I end up spinning my wheels trying to get something to work, only to find on a subsequent search that I should do it differently (or vice versa....)

For example, with EF 5 (which I think is version 4 - another confusing topic), EF switched to a DBContext. If I want to implement code on load and on save, do I still have to modify the templates in VS so that the necessary code is generated each time I update the edmx? Or should I do as some suggest which is use the objectContext instead? While I want answers to these (and other related) questions, I am MUCH more interested in learning where I can find out the "current" way to do these things with EF.

Thanks

Julia Lerman's books are still relevant, and I would recommend reading her books on EF Code First and EF DBContext. This will get you close to up to date on EF code first. EF 4.3 and above is still relevant to building EF solution. After you have looked at the two books you can proceed over to ADO.NET Blog which will get you information on new feature of EF 5 and some other good videos.

It is worth noteing that EF is open source and an evolving api and you can view release notes and the like on their codeplex site.

I'm working on an MVC4 application that uses Entity Framework 5, database migrations, and the asp membership api. In my development environment I can delete my database entirely, run a package (.zip), refresh the page and all works as expected; a database gets created, the seed method is called and some default values are stuck into the database.

Perfect, really easy too! But.....yes, there is always a but!

When I go to deploy this same package(only changed the db connection string) and run this in a remote environment, the behavior changes. Again, if I go in and delete the database entirely, run the package (.zip), refresh the page, the database gets created with only the asp membership api tables. I've checked the connection string, and that is for sure, not the cause, or else the database and membership tables couldn't get created.

I am aware of using the nuget package manager, which is really a powershell instance, but I am not using it since it cannot be used in the production environment. I'd like the package to handle it all, and in my test environment, it works perfectly.

Does anyone have any suggestions? Could this be a side effect of mixed migration history?

Thanks in advance!

The default MVC4 Internet Application project messes up a lot of people. Microsoft wanted to demonstrate the SimpleMembership functionality, which requires an EF context, but it's not common sense that you have to actually modify this portion to effectively use the rest of your app.

So, a little primer on how Entity Framework works will help clear up why this happening I think.

Entity Framework (at least version 5, it may change in 6 or successive versions) only allows one DbContext for your application. Most likely, you have at least two, the AccountsContext that was autogenerated by the project template and the context you use for the rest of your application. If you were to turn off automatic migrations and attempted to generate a migration, EF would helpfully tell you that you need to specify which context to use. However, automatic migrations are the default in Code First, very few disable that, and thus very few ever get alerted.

When automatic migrations are enabled, and you have no existing database, EF happily (and silently) creates the database for you from your context. But, what if you have multiple contexts? Well, the other nasty little feature of EF is that it creates the database just-in-time. So, which context gets used is a function of which one is accessed first. Nice, huh? So, if you attempt to do anything like a logon, then the database is created from the AccountsContext and then, when you try to access something from your app's context, the database already exists, and EF does nothing.

So, what to do about this? Well, you need one context to remove ambiguity. You can still have more than one context if you want in your app, but you have to essentially tell EF that all the other contexts are database-first, i.e. don't do anything.

public class AccountsContext : DbContext
{
    public AccountsContext()
        : base("name=YourConnectionStringName")
    {
        Database.SetInitializer<AccountsContext>(null);
    }

    ...
}

public class MyAppContext : DbContext
{
    public MyAppContext()
        : base("name=YourConnectionStringName")
    {
    }

    // All your entities here, including stuff from AccountsContext

}

MyAppContext will be your "master" context, which will have every entity in your database that EF should know about. The base call on both serves to take EF's guessing out of of the way and explicitly make sure everyone is one the same page as to what database connection should be used. Your AccountsContext is now essentially database-first, so it won't spark EF to create the database or attempt any migrations -- that's what MyAppContext is for. You can create other contexts in the same way as AccountsContext to break up your app's functionality; you just have to mirror any DbSet property declarations into your "master" context.

Julie Lehrman calls this concept "bounded contexts" in her book, Programming Entity Framework: DbContext, and presents a generic class you can inherit all of your "bounded contexts" from, so you don't have to specify the connection string name and set the database initializer to null each time.

While I was reading Programming Entity Framework: DbContext on Creating an IDbSet Implementation "Julia Lerman" uses the ObservableCollection for making the fake DbSet items but I've seen on other implementations like this one which is pointed on the same book also it uses HashSet for items. Which one is better to use and why?

I'm having a difficult time figuring out how to update my entities and their related data. Using Lazyloading..

I have the following entity models

public class Config
{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public Int32 Id { get; set; }

    [Required]
    [MaxLength(100)]
    public String Name { get; set; }

    public virtual IList<DataField> DataFields { get; set; }
}

public class DataField
{
    [Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public Int32 Id { get; set; }

    [ForeignKey("Config")]
    public Int32 ConfigId { get; set; }

    public virtual Config Config { get; set; }

    [Required, MaxLength(1000)]
    public String Name { get; set; }
}

With the corresponding view models. I've stripped them down, removed validations and such.

public class ConfigViewModel
{
    public Int32 Id { get; set; }

    public String Name { get; set; }

    public IList<DataFieldViewModel> DataFields { get; set; }

    public ConfigModel()
    {
        DataFields = new List<DataFieldViewModel>();
    }
}
public class DataFieldViewModel
{
    [Required]
    public Int32 Id { get; set; }

    public String Name { get; set; }
}

In my Edit.cshtml form I dynamically add new datafields, and when I post the form, they are properly deserialised to ConfigViewModel.DataFields. So long everything is working. But how do I convert these models, and update the entitymodels? If I post new datafields, their id's will be 0, and they should be added, but the ones that already have an Id, should be updated.. I don't know how to do this, and can't find anything related, or that I could understand.

I have the following in my ConfigController.

[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit(ConfigViewModel model)
{
    try
    {       
        if (!ModelState.IsValid)
            return View();

        var config = uow.Repository<Entity.Models.Config>().FindById(model.Id);

        config.Name = model.Name;

        // Do something with the datafields
        // config.DataFields

        uow.Repository<Entity.Models.Config>().Edit(config);
        uow.Save();

        return RedirectToAction("Index");
    }
    catch(Exception ex)
    {
        ModelState.AddModelError("Error", ex.Message);
        return View(model);
    }
}

In my repository I have:

public void Edit(TEntity entity)
{
    var entry = Context.Entry<TEntity>(entity);
    entry.State = EntityState.Modified;
}

My Edit.cshtml form looks like

@for(var i = 0; i < Model.DataFields.Count; i++)
{
    <tr>                         
        <td>@Html.HiddenFor(m => m.DataFields[i].Id)</td>
        <td>@Html.TextBoxFor(m => m.DataFields[i].Name)</td>
        <td>@Html.EnumDropDownListFor(m => m.DataFields[i].Type)</td>
    </tr>
}

It looks like a couple of things are happening here.

If I understand your data structures correctly, you have a Config object that has zero or more DataField objects associated with it.

The Edit page of your application for editing Config objects allows you to add new DataField items or modify existing DataField items.

I'm assuming that in the commented section of your example:

// Do Something with the DataFields
// config.DataFields

that you're translating the View Models back to your domain objects.

Now I'm going to assume that you are using a per-request lifetime for the DbContext, as that's most typical in these scenarios. So, on each web request, a new DbContext is instantiated as part of the instantiation chain of the MVC Controller and its dependencies (e.g. services, repositories, unit of work, etc.). So on this new request for editing Config objects, the DbContext is empty—it has no knowledge of any objects because it's a brand new DbContext.

At this point, you need to Attach the Config entity to the DbContext so that the DbContext will start tracking it. If anything changed about the Config entity (e.g. was the name changed, or were new DataField objects added to the collection?), you will need to set the state of the entity within the DbContext to Modified (this you have done in your example above).

Attaching the Config entity to the DbContext will also result in attaching all the related DataField objects that are referenced by the edited Config entity. But there's a slight wrinkle. You will need to tell the DbContext which entities are new, and which are modified. You can easily tell new entities from modified entities because the DataField.Id property will be 0. But how do you tell if an existing DataField entity has been returned unchanged? This is important, because simply attaching the DataField entities to the DbContext puts them in an Unmodified state within the context. So, if there were any changes on an existing entity, those changes would not be persisted when committing the context.

A naive approach to solve this problem would entail setting all DataField entities whose Id property is non-zero to the Modified state. This will increase load on the database (but for a small application, this will be negligible). However, if you have any triggers or some other mechanism for auditing when records are created or updated, this is not a good solution. Assuming you are not performing auditing, the naive approach may work well:

public void Edit(TEntity config)
{
    Context.Attach<TEntity>(config);
    Context.Entry<TEntity>(config).State = EntityState.Modified;

    foreach(var df in config.DataFields)
    {
        Context.Entry<DataField>(df).State = EntityState.Modified;
    }

    // I noticed you never saved the changes to the DbContext. Do you need
    // to do this here, or are you doing it with your UOW somewhere else??
    Context.SaveChanges();
}

Again, this is a naive approach that should generally work well for small applications. At the very least, it should give you a better idea of the kinds of things you need to be aware of when working with Entity Framework in a disconnected N-Tier scenario.

Also, I highly recommend you check out the following books:

Each of those books discusses the scenario you're talking about. You may want to start with the Code First book since you are using code first.

HTH

I'm having some troubles with validation on my application. Let's say I've the following models:

    public class Company
    {
        public int id { get; set; }
        [Required]
        public String Name { get; set; }
        public String Location { get; set; }
        public List<Contacts> Contacts { get; set; }
    }

    public class Contact
    {
        public int id { get; set; }
        [Required]
        public String Name { get; set; }
        [DataType(DataType.EmailAddress)]
        public String Email { get; set; }
        public String Telephone { get; set; }
        public String Mobile { get; set; }
    }

Now in my company create view I've two buttons, one to add contacts to the company, and another one to create the new company. I detected which button was used in my controller like this (both buttons are named "button"):

    [HttpPost]
    public ActionResult Create(String button, FormCollection collection)
    {
        if(button == "AddContact")
        {
            AddContact(collection);
        }
        else
        {
            CreateCompany(collection);
        }
    }

While it's being created the object that represents the company that it's being create is stored in the session (for example HttpContext.Session["company"] = company;)

Now the problem is that if, for example, I try to add a contact without first specifying the company name, i get a validation error because the company name is required, which shouldn't happen because the user might want to add the contacts before adding the company info. Or if I try to save the company, I also get a validation error, because usually when saving the "add contact" form is empty, which means that the contact name (which is required as well) was not specified.

What I want to know is that if it's possible to validate the contact properties only when the addContact button is used, and validate the company properties only when the createCompany button is pressed.

For now i only need to do this serve-side, but if anyone has a solution to do this client-side as well i would appreciate the help.

You can provide conditional validation using the Entity Framework by overriding DbEntityValidationResult in the DbContext. When this validation occurs in the DbContext you can access other entities. When validating a contact you can check the company too. For example:

    protected override DbEntityValidationResult ValidateEntity(DbEntityEntry entityEntry, IDictionary<object, object> items)
    {
        var result = base.ValidateEntity(entityEntry, items);
        ValidateContact(result);
        return result;
    }

    private void ValidateContact(DbEntityValidationResult result)
    {
        var contact= result.Entry.Entity as Contact;
        if (contact!= null && contact.ContactId != 0)
        { 
            // Add validation code here, such as:
            if(!string.IsNullOrEmpty(contact.Company.Name){ 
                     result.ValidationErrors.Add(
                     new DbValidationError(
                       "Contact",
                       "Company name cannot be null or empty when validating contacts.")
                     );
            }
        }
    }

See Julia Lerman's Programming Entity Framework: DbContext http://www.amazon.com/Programming-Entity-Framework-Julia-Lerman/dp/1449312969 for more details.

The ADO.NET Entity Framework (EF) is .NET's Object-Relational Mapping (ORM) tool that enables .NET developers to work with relational data using domain-specific objects. It eliminates the need for most of the data-access code that developers usually need to write. Either natively, or through third-party libraries, it supports most major RDBM products including SQL Server, MySQL, Oracle, PostgreSQL and SQLite. It also supports Microsoft's "LINQ" syntax and lambda-expressions via the LINQ to Entities library.

Visual Studio provides design-time support for EF. It includes GUI tools for model-to-database and database-to-model generation. The .NET Text Template Transformation Toolkit (T4) or text-templating libraries are leveraged to generate entity classes, and this code generation is customizable in various ways from within Visual Studio.

Initial Release:

August 11, 2008

Stable Release:

6.1.3 (March 10, 2015)

References

Books