Daily Archives: February 14, 2010

Defining Constraints in an EF4 model that don’t exist in the database

In the first version of Entity Framework, if you wanted to create a PK/FK association between entities where there was no such constraint defined in the database you have to manually edit the SSDL (and lose that edit if you update the model from db).

Why would you want to do this? The typical use case is when you are stuck with a database that is poorly designed and you are not allowed to make changes to it.

In Entity Framework 4, as long as the Primary Keys are defined in the db (otherwise the entities are read only like views, although you can map stored procs to them and make them updatable) and you have foreign keys in the model, you can define the constraint easily.

Here’s a dependent table. It does have a foreign key property (with a typo :)) but notice under indexes there is no PK_FK defined pointing back to the table which PrimartyID(sic) refers to.

 

noconstraint

 

When I pull this table and PrimaryTable into the model there is no association between them.

I create an association:

noconstraint2

and then define the constraint in the model. You need to open the properties window of the association and then click on the Referential Constraint ellipses

noconstraint2a

to get to the ref constraint dialog:

noconstraint3

This is a new feature that comes with foreign key associations. You can’t do this if you do not include foreign key ids in your model.

Now for the test:

  private static void fakePKFK()
    {
      var context = new manytomanytestEntities();
      var list = context.PrimaryTables.Include("DependentTables").ToList();
      var firstPrimary = list[0];
      var newDependant = new DependentTable {DependentName = "ChildNew for FIrst"};
      firstPrimary.DependentTables.Add(newDependant);
      context.SaveChanges();
    }

And it works. THe query returns graphs of primary & dependents. The SaveChanges inserts a new dependent. Rerunning the code brings me back the new dependent in the primary’s collection.

Have not tested *:*. Someone has already asked me about code only. I don’t know. But feel free to take the time to test it out and let me know! 🙂

Entity Framework ObjectContext and Reporting

I had an email this morning from someone who was having trouble with reports populated using Entity Framework.

He was running a report repeatedly but changing the filter.

For example, Customers whose last name is Smith, then Customers whose last name is Barber.

The problem was that after running the Smith report, the Smiths were showing up on the Barber report.

The problem is that he was using one context to generate both reports.

The context just keeps collecting all of the entities you feed into it. More accurately, the context keeps collecting ObjectStateEntries (which manage the state for an instantiated entity and act as pointers back to the entity objects in memory) for all of the entities you feed to it.

Best to just have a context that exists only for the life time of the method which gets the report data.

Public List<Customer> GetCustomers(string lastname)
{
   using (var context=new MyEntities()) 
  {
     return context.Customers.Where(c=>c.LastName==lastname).ToList();
  }
} 

Now you don’t have to worry about cached entities. 

This is not a hard rule but a guideline. For example, one exception would be when you are drilling in to reports.