Answered by:
How to retrieve an entity by Id and EntitySetName

Question
-
So, for example IEntityObject entityObject = GetEntityByIdAndEntitySetname ("Customers", 56)
The non-reflexive way would be:
IEntityObject entityObject = this.DataWorkspace.ApplicationData.Customers.Where(x => x.Id == referenceId).SingleOrDefault();
I found already how to access the Customer entity set by name, but then I get lost
this.DataWorkspace.ApplicationData.Details.Properties.All().Where(e => e.Name == "Customers").SingleOrDefault()
The above would be very helpful in cases where you don't want to store hard foreign key relations in tables, but you just want to store a "weak" foreign key field together with a string field indicating to which table the foreign key refers.Thanks a lot in advance for the help.
paul van bladel - KBC BANK
paul van bladel
Thursday, June 23, 2011 6:18 PM
Answers
-
If you want a way to retrieve entities by their key segments I would suggest using the built in SingleOrDefault queries for this.
So instead of calling:
IEntityObject entityObject = this.DataWorkspace.ApplicationData.Customers.Where(x => x.Id == referenceId).SingleOrDefault();
I would suggest calling:
IEntityObject entityObject = this.DataWorkspace.ApplicationData.Customers_SingleOrDefault(referenceId);
This is fairly easy to do in a weakly typed way without using reflection. The example below is fairly abstract in that it is not tied to a specific data source and it can handle attached entities that have multiple key segments.
public static IEntityObject GetEntityByKey(this IDataService dataService, string entitySetName, params object[] keySegments) { ICreateQueryMethod singleOrDefaultQuery = dataService.Details.Methods[entitySetName + "_SingleOrDefault"] as ICreateQueryMethod; if (singleOrDefaultQuery == null) { throw new ArgumentException( "An EntitySet SingleOfDefault query does not exist for the specified EntitySet.", entitySetName); } ICreateQueryMethodInvocation singleOrDefaultQueryInvocation = singleOrDefaultQuery.CreateInvocation(keySegments); return singleOrDefaultQueryInvocation.Execute() as IEntityObject; }
The following code shows the usage:
IEntityObject entity = this.DataWorkspace.ApplicationData.GetEntityByKey("Customers", 1);
HTH
- Proposed as answer by Michael Simons (MSFT)Microsoft employee Friday, June 24, 2011 1:45 PM
- Marked as answer by Paul Van Bladel Friday, June 24, 2011 2:51 PM
Friday, June 24, 2011 1:45 PM
All replies
-
I think ultimately, you will have to cast to a type to get any kind of typed query. But maybe something like this will work for you.
partial void Test_Execute() { // Parent var contact = this.DataWorkspace.ApplicationData.Contacts.Where(c=>c.Note!=null && c.Note.Length > 0).FirstOrDefault(); Contact mgr = null; string[] fields = contact.Note.Split(':'); if (fields.Length >= 2) { string table = fields[0]; string managerName = fields[1]; // Find Related mgr = this.DataWorkspace.ApplicationData.Contacts.Where(c => c.First == managerName).FirstOrDefault(); } if (mgr == null) this.ShowMessageBox("No Manager. Lone Wolf"); else this.ShowMessageBox("Manager is: " + mgr.FullName); }
Friday, June 24, 2011 5:41 AM -
Hi,
I'm sorry, I must have formulated my question in an unclear way.
I basically want to interrogate the applicationdata and get an entity by ID but I want to specify the entity by its name.
So, the signature of the functionaly I want boils down to:
IEntityObject entityObject = GetEntityByIdAndEntitySetname ("Customers", 56)
or
IEntityObject entityObject = GetEntityByIdAndEntitySetname ("Orders", 24)
Thanks for the help anyhow !
paul.
paul van bladelFriday, June 24, 2011 6:37 AM -
If you want a way to retrieve entities by their key segments I would suggest using the built in SingleOrDefault queries for this.
So instead of calling:
IEntityObject entityObject = this.DataWorkspace.ApplicationData.Customers.Where(x => x.Id == referenceId).SingleOrDefault();
I would suggest calling:
IEntityObject entityObject = this.DataWorkspace.ApplicationData.Customers_SingleOrDefault(referenceId);
This is fairly easy to do in a weakly typed way without using reflection. The example below is fairly abstract in that it is not tied to a specific data source and it can handle attached entities that have multiple key segments.
public static IEntityObject GetEntityByKey(this IDataService dataService, string entitySetName, params object[] keySegments) { ICreateQueryMethod singleOrDefaultQuery = dataService.Details.Methods[entitySetName + "_SingleOrDefault"] as ICreateQueryMethod; if (singleOrDefaultQuery == null) { throw new ArgumentException( "An EntitySet SingleOfDefault query does not exist for the specified EntitySet.", entitySetName); } ICreateQueryMethodInvocation singleOrDefaultQueryInvocation = singleOrDefaultQuery.CreateInvocation(keySegments); return singleOrDefaultQueryInvocation.Execute() as IEntityObject; }
The following code shows the usage:
IEntityObject entity = this.DataWorkspace.ApplicationData.GetEntityByKey("Customers", 1);
HTH
- Proposed as answer by Michael Simons (MSFT)Microsoft employee Friday, June 24, 2011 1:45 PM
- Marked as answer by Paul Van Bladel Friday, June 24, 2011 2:51 PM
Friday, June 24, 2011 1:45 PM -
Hi snomis,
Thank you so much for sharing this brillant piece of code with us.
I have still one missing link now.
I want server side to be able to retrieve from an entity of type "EntityObject" the corresponding EntitySet Name.
It's very straightforward to get the Entity name (e.g. Customer) from an EntityObject, but I can't find a way to retrieve the EntitySetName (e.g. Customers) from an EntityObject.
I call this code server side in
partial void Customers_Updating(Customer entity) { // string entitySetName = .... from entity }
Obviously, in most cases the difference between the entityName and the entitySetName is just adding an 's", but of course it depends on the pluralization rules.thanks in advance
Paul Van Bladel - KBC BANK
paul van bladelFriday, June 24, 2011 2:51 PM -
Sorry, disregard my last question. I found the answer myself :)
To get the entitysetname is very straightforward:
var entitysetName = entity.Details.EntitySet.Details.Name;
paul van bladelFriday, June 24, 2011 3:11 PM -
public static IEntityObject GetEntityByKey(this IDataService dataService, string entitySetName, params object[] keySegments) { ICreateQueryMethod singleOrDefaultQuery = dataService.Details.Methods[entitySetName + "_SingleOrDefault"] as ICreateQueryMethod; if (singleOrDefaultQuery == null) { throw new ArgumentException( "An EntitySet SingleOfDefault query does not exist for the specified EntitySet.", entitySetName); } ICreateQueryMethodInvocation singleOrDefaultQueryInvocation = singleOrDefaultQuery.CreateInvocation(keySegments); return singleOrDefaultQueryInvocation.Execute() as IEntityObject; }
Friday, June 24, 2011 4:52 PM