Dynamically query entities from Entity Framework for association to primary Entity

c# dynamic-queries entity-framework expression-trees reflection

Question

I recognize that the title wasn't the best, but this is what I really want to do.

Entity1 and its relationships are represented in a details view that I have. The property names and values are being stored as a key/value pair. To change the Entity attributes to the appropriate values for non-associations, I am presently utilizing reflection. I don't think this is the most effective approach, but I haven't been able to use Expression Trees to discover a more effective one. As a result, I now need to assign Entity1's associations to their matching entities based on their main keys, let's name them Entity2-4.

I'm not sure how to build a dynamic query to Entity2-4 and set Entity1.association to the appropriate entity while iterating the properties of Entity1. This is the code I currently have:

foreach (string k in e.Values.Keys)
{
    if (e.Values[k] != null && !String.IsNullOrEmpty(e.Values[k].ToString()))
    {
        System.Type objectType = Entity1.GetType();
        PropertyInfo[] p = objectType.GetProperties();

        foreach (PropertyInfo pi in p)
        {
            // set Entity1.Property for non associations (works just fine)
            if (pi.Name == k)
            {
                System.Type t = pi.PropertyType;
                pi.SetProperty(e.Values[k].ToString(), Entity1);
                break;
            }
            // when i see pi.Name contain Reference, I know I'm working on an association
            else if (pi.Name.Contains("Reference"))
            {
                // k is in the form of Entity.Property
                var name = pi.Name.Left("Reference");
                var keys = k.Split('.');
                var ent = keys[0];
                var prop = keys[1];
                if (name == ent)
                {
                    // here I need to obtain an instance from the db
                    // ie generate my dynamic query to the Entity with the name
                    // contained within the var "ent"

                    // I tried using reflection and could instantiate the entity 
                    // but it did me no good as I needed the entity from the db

                    var entityInstance = some dynamic query;

                    // here I need to set the association of Entity1 to entityInstance from above
                    // normally I would use reflection, but I'm not sure that would work
                    // since EntityReference is the actual property returned by reflection
                    Entity1.SetAssocation(prop, Entity2);
                    break;
                }
            }
        }
    }
}

EDIT

In order to submit the entity and association entities to the data context, I essentially need to generate the entities. Entity 2 through 4 already exist in the database; I must query it to find the instances so that I can link them to the new Entity 1 that I am creating and submitting.

My default model:

Entity1

Entity1.ID
Entity1.Prop1
Entity1.Prop2
Entity1.Prop3
Entity1.Entity2
Entity1.Entity3
Entity1.Entity4

Entity2

Entity2.ID
Entity2.Name

Entity3

Entity3.ID
Entity3.Name

Entity4

Entity4.ID
Entity4.Name
1
1
4/10/2013 9:08:12 PM

Popular Answer

We've spoken extensively about how to obtain themetadata beyond theDbContext . These links can help you get started. I'll also make a few more specific remarks.

How can I programmatically read the info from an EF DbContext?

A brief synopsis (but be sure you visit there for more) is as follows:

using (var db = new MyDbContext())
{
    var objectContext = ((IObjectContextAdapter)db).ObjectContext;
    var container = objectContext.MetadataWorkspace.GetEntityContainer(objectContext.DefaultContainerName, DataSpace.CSpace);

    var dependents = ((EntitySet)(set)).ForeignKeyDependents;
    var principals = ((EntitySet)(set)).ForeignKeyPrincipals;
    var navigationProperties = ((EntityType)(set.ElementType)).NavigationProperties;

    // and e.g. for many-to-many (there is more for other types)
    ManyToManyReferences = navigationProperties.Where(np =>
        np.FromEndMember.RelationshipMultiplicity == RelationshipMultiplicity.Many &&
        np.ToEndMember.RelationshipMultiplicity == RelationshipMultiplicity.Many)
        .Select(np => Extensions.CreateLambdaExpression<TEntity>(np.Name))
        .ToList();
}

Great work was done by @Goran Obradovic to turn what I began into a collection of reusable queries (my due credits to him:).

All other types of information that are there have been figured out by myself. This only applies to theDataSpace.CSpace (which is the most beneficial to you), but there is alsoDataSpace.SSpace etc., which are more useful for developing SQL queries, etc. Most of the links will be near the bottom.


Specifics:
In your situation, the following might be useful:
(Note: I'm not completely sure what you're looking for, butguess what way are you traveling in here?)
db.Set<Worker>().Find(1);

Is the standard technique for obtainingDbSet for a certain entity.

You may also create it using aType If you want it to be entirely dynamic, for instance...
(I have always want to accomplish this:)

MethodInfo setMethod = typeof(DbContext).GetMethod("Set", new Type[]{});
MethodInfo genericSetMethod = setMethod.MakeGenericMethod(new Type[] { typeof(YourEntity) });
var set = genericSetMethod.Invoke(db, new object[] {});  

Put your organization - orType in place oftypeof(YourEntity) .

Then, you may ask that question, for instance.Find(id) - to get specific values for that object, etc.

I'm not sure if you want anything that dynamic, but that's as dynamic as it gets. I'm just putting this information out there in case you need it.

At the very least, I hope it will get you started.


links:
(all are my postings; some may be more or less pertinent, but they could be helpful.)
How can I programmatically read the info from an EF DbContext?
How can unit testing verify that attributes marked in the ORM model are computed?
Using a supplier that doesn't provide CreateDatabase, get the Model schema needed to build a database programmatically.
Data transformation by program during EF5 Code First migration
3
5/23/2017 10:25:13 AM


Related Questions





Related

Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow