.Net Entity Framework Adding New Objects in N-Tier Environment
Posted: November 19, 2008 Filed under: .Net Entity Framework 3.5 SP1 | Tags: Entity Framework Leave a comment »Through out my my career as a Application Developer; this thought runs through my head when using new technology such as the Entity Framework, “Is there something wrong with me, how come new technology makes me feel like I have a lack of brain cells, or my neural networks didn’t develop properly when younger, or am I simply mad?” Making great enterprise applications is my goal. When something like the Entity Framework comes out I am immediatly drawn to the potentials of such a framework.
My problem; I have N-Tier environment, with WCF service that uses the Entity Framework. The service contains a method:
WCF Service Method ———-
public void AddStore(Stores newStore)
{
using (CorporateEntities ce = new CorporateEntities())
{
newStore.CreatedDate = DateTime.Now;
ce.AddObject("Stores", newStore);
ce.SaveChanges();
}
}
END of Method ——-
Stores is the entity from my data model. Awesome. Simple cool. However it isn’t this simple. To get this to work on client side I had to do this. You would think you could simply pass in a Store object and add it. LOL, nooooooo. That would be crazy.
Client Code That works ———
Stores newStore = new Stores(); /* Why cant assign it like this newStore.Concepts = client.GetConcept(0); because we can't sorry doesn't work */ Concepts concept = client.GetConcept(0); Distributors dist = client.GetDistributor(1); StoreStatus status = client.GetStat(1); POSSystems pos = client.GetPOSSystem(1); newStore.LongName = "The besttes store in the whole world"; newStore.ShortName = "Awesomeness"; newStore.ID = 666; newStore.IsActive = false; newStore.IsGroups = false; newStore.IsKidsBirthdays = false; newStore.IsLab = false; newStore.IsReservations = false; newStore.IsShowWeb = false; newStore.IsTakeOut = false; newStore.IsWheelChairAccessible = false; /* This is what we do to get it to work .... not pretty*/ EntityReferenceOfStoreStatusexoxzxyP statusReference = new EntityReferenceOfStoreStatusexoxzxyP(); statusReference.EntityKey = status.EntityKey; newStore.StoreStatusReference = statusReference; EntityReferenceOfConceptsexoxzxyP conceptReference = new EntityReferenceOfConceptsexoxzxyP(); conceptReference.EntityKey = concept.EntityKey; newStore.ConceptsReference = conceptReference; EntityReferenceOfPOSSystemsexoxzxyP posReference = new EntityReferenceOfPOSSystemsexoxzxyP(); posReference.EntityKey = pos.EntityKey; newStore.POSSystemsReference = posReference; EntityReferenceOfDistributorsexoxzxyP distroReference = new EntityReferenceOfDistributorsexoxzxyP(); distroReference.EntityKey = dist.EntityKey; newStore.DistributorsReference = distroReference; client.AddStore(newStore);
End of that works Client Code ———————————–
Wow, Weird eh?!?!? It would be great just to do.
Stores newStore = new Stores(); newStore.Concepts = client.GetConcept(1);
then simply:
client.AddStore(newStore);
You can try attaching the referenced table objects, etc, but no matter what you do you may see exceptions like:
“An object with the same key already exists in the ObjectStateManager. The existing object is in the Unchanged state. An object can only be added to the ObjectStateManager again if it is in the added state.”…
Update Nov 21, 2008
Ok, so an update. I am leaving the post as is. Just to see the steps I have gone through and some wierd ways to make inserting objects in N-Tier environment work. Here is some updated code on solution that is better, but still far from ideal!
–Updated WCF Method
public void AddStore(Stores newStore, Concepts concept, StoreStatus status, Distributors distributors, POSSystems pos)
{
using (CorporateEntities ce = new CorporateEntities())
{
EntityReference<Concepts> c = new EntityReference<Concepts>();
c.EntityKey = concept.EntityKey;
newStore.ConceptsReference = c;
EntityReference<StoreStatus> s = new EntityReference<StoreStatus>();
s.EntityKey = status.EntityKey;
newStore.StoreStatusReference = s;
EntityReference<Distributors> d = new EntityReference<Distributors>();
d.EntityKey = distributors.EntityKey;
newStore.DistributorsReference = d;
EntityReference<POSSystems> p = new EntityReference<POSSystems>();
p.EntityKey = pos.EntityKey;
newStore.POSSystemsReference = p;
newStore.CreatedDate = DateTime.Now;
ce.AddObject("Stores", newStore);
ce.SaveChanges();
}
}
and then a more clean client code with the weirdness of having to pass in the Navigation or Relationship objects for the change.
/*client is the WCF instance*/ client.AddStore(newStore, client.GetConcept(0), client.GetStat(1), client.GetDistributor(1), client.GetPOSSystem(1));
A little better, a little cleaner, a little weird still. All the get methods used in the method parameters are WCF methods(Just to clarify).
Some nice web sources explaining that we will have to deal with this elegant retarded framework. Check it out. We will be dealing with these nuances for awhile. Typical!
End of Nov, 21, 2008 update
This is what worked for me. Kind of like WTF, “This is what I have to do to add a new object that has foreign key relationship with other tables….?” Yup, No access to the ID fields of the related objects just the object itself. All I want to do is only deal with objects on the presentation layer. I don’t want the presentation layer to know that I am using the entity framework, but unfortunately I have not seen any better solutions.
Thats it for now, peeps.