Question

I have created an n-tier solution where I am retrieving related data from a WCF service, updating it within a Windows Forms application, and then returning the updated data via WCF to be persisted to the database. The Application, WCF Service and Database are all on different machines.

The data being retrieved consists of an object and child objects...

public Product Select(string catalogueNumber) {

  return (from p in this.ProductEntities.Products.Include(@"Tracks")
            where p.vcCatalogueNumber == catalogueNumber
            select p).FirstOrDefault() ?? new Product();
}

The updates being applied by the client application can, as well as updating existing content, also insert additional "Track" objects.

When I receive the Product object back from the client application, I can see all of the updates correctly, however in order to save all of the changes correctly I have to jump through a few hoops...

public void Save(Product product) {

    Product original = this.Select(product.vcCatalogueNumber);
    if (original.EntityKey != null) {

        this.ProductEntities.ApplyPropertyChanges(product.EntityKey.EntitySetName, product);

        // There must be a better way to sort out the child objects...
        foreach (Track track in product.Tracks.ToList()) {

            if (track.EntityKey == null) {
                original.Tracks.Add(track);
            }
            else {
                this.ProductEntities.ApplyPropertyChanges(track.EntityKey.EntitySetName, track);
            }

        }

    }
    else {

        this.ProductEntities.AddToProducts(product);

    }

    this.ProductEntities.SaveChanges();

}

Surely, there has to be an easier way to do this?

Note: I have spent the better part of the afternoon investigating the EntityBag project, but found that this has not been updated to work with EF RTM. In particular, whilst it will successfully update the existing data exceptions are thrown when mixing in new objects.

Was it helpful?

Solution

I don't have a ready-made answer for your particular scenario - but just a question: have you checked out ADO.NET Data Services (f.k.a. "Astoria") ?

They're built on top of Entity Framework, WCF's RESTful interface, and they offer a client-side experience, plus they also seem to have a decent story for not just querying, but also updating, inserting records into databases.

Could this be an option?

Check them out on MSDN, at David Hayden's blog, on Channel9, or see some of the excellent sessions at MIX08 and MIX 09

Marc

OTHER TIPS

You should probably take a look at Danny Simmons' EntityBag sample.

It is designed to simplify these sorts of issues: http://code.msdn.microsoft.com/entitybag/

As CatZ says things will be a lot easier in .NET 4.0.

One of the things we are planning on doing to help is creating a T4 template for you that generates classes for you that are capable of self-tracking, and some extra surface to make it simple for these self-tracking entities to ApplyChanges() to the context when they get back to the server tier.

Hope this helps

Cheers Alex (PM on the Entity Framework team at Microsoft).

I see that this thread is quiet followed, so I allow myself to do a little update...

Weeeeee ! Self-Tracking entities has arrived in EF 4!

Check this out:

http://blogs.msdn.com/efdesign/archive/2009/03/24/self-tracking-entities-in-the-entity-framework.aspx
Explanation of the self-tracking mechanism by the entity framework team.

http://aleembawany.com/2009/05/17/new-features-in-entity-framework-40-v2/
Anouncement of new features in EF 4.

http://msdn.microsoft.com/en-us/magazine/ee321569.aspx
Comparison of several N-Tier patterns for disconnected entities.

Enjoy !

In Entity Framewrok 4 you can use the method "ApplyCurrentValues" to update a detached entity.

In your scenario will be something like this:

this.ProductEntities.Product.ApplyCurrentValues(product);
foreach (Track track in product.Tracks.ToList()) {
if (track.EntityKey != null)
{
//Update Entity
  this.ProductEntities.Track.ApplyCurrentValues(track);
}
else
{   
  //New Entity
  this.ProductEntities.Track.Attach(track);
}

}

I hope it will be useful

One of the limitations of Entity Framework v1.0 is Updating Entities. Unfortunately I think you are out of luck until version 2 arrives.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top