从实体框架中动态查询实体以关联到主实体



我知道这个标题不是最好的,但这是我真正想要完成的。

我有一个表示Entity1及其关联的详细视图。我正在捕获键/值对中的属性名称和值。我目前正在使用反射将实体属性设置为非关联的相应值。我怀疑这是最有效的方式,但我一直无法找到一个更好的方式使用表达式树。因此,现在我需要根据实体关联的主键将Entity1的关联设置为相应的实体,称其为Entity2-4。

当迭代Entity1的属性时,我不知道如何构造一个动态查询Entity2-4并设置Entity1。关联到相应的实体。下面是我到目前为止的代码:

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;
                }
            }
        }
    }
}

编辑

我基本上需要构造实体及其关联实体,以便我可以将它们提交到数据上下文。实体2到实体4存在于数据库中,我需要查询数据库以获取实例,我可以将它们关联到我正在创建并准备提交的新实体1。

我的基本模型:

Entity1

Entity1.ID
Entity1.Prop1
Entity1.Prop2
Entity1.Prop3
Entity1.Entity2
Entity1.Entity3
Entity1.Entity4
<<strong> Entity2 strong>
Entity2.ID
Entity2.Name

Entity3

Entity3.ID
Entity3.Name

Entity4

Entity4.ID
Entity4.Name

我们就如何从DbContext中得到metadata进行了深入的讨论。这里有一些链接,让你开始。我会补充一些具体的评论。

如何以编程方式读取EF DbContext元数据?

一个简短的总结(但你应该在那里查看更多):

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();
}
@Goran Obradovic做了一个伟大的工作,将我开始的内容打包成一组可重用的查询(我要感谢他:)。

我已经算出了里面所有其他类型的信息。这只是DataSpace.CSpace(这是对你最有用的),但也有DataSpace.SSpace等-这是更多的创建SQL查询等。我会把大多数链接放在底部。


细节:
以下内容可能对您有所帮助:
(注:我不完全确定你是什么后,但我试图guess这里是什么方向,你的方向)

db.Set<Worker>().Find(1);

是访问特定实体的DbSet的通用方法。

你也可以从Type构建它,如果你需要它是完全动态的,例如....
(我一直想这样做:)

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

把你的实体-或你的Type代替typeof(YourEntity)

然后您可以继续查询例如Find(id) -对于该实体-以获得具体值等。

这是最动态的-我不确定这是否是你想要的-但我只是把东西扔在这里,以防你需要它。

至少我希望这能让你开始。


链接:
(都是我的帖子-有些可能或多或少相关,但可能会有所帮助)
我如何以编程方式读取EF DbContext元数据?
如何通过单元测试检查属性标记为在ORM模型中计算?
获取模型模式以编程方式使用不支持createddatabase的提供程序创建数据库
EF5 Code First迁移中的程序化数据转换

因此,我无法动态执行此操作。但这是我的解决方案。有人能就如何动态地执行此操作提出建议吗?

foreach (string k in e.Values.Keys)
{
    if (e.Values[k] != null && !String.IsNullOrEmpty(e.Values[k].ToString()))
    {
        System.Type objectType = roster.GetType();
        PropertyInfo[] p = objectType.GetProperties();
        foreach (PropertyInfo pi in p)
        {
            if (pi.Name == k)
            {
                System.Type t = pi.PropertyType;
                pi.SetProperty(e.Values[k].ToString(), roster);
                break;
            }
            else if (pi.Name.Contains("Reference"))
            {
                var name = pi.Name.Left("Reference");
                var keys = k.Split('.');
                var entityName = keys[0];
                var prop = keys[1];
                if (name == entityName )
                {
                    var val = e.Values[k].ToString();
                    switch (pi.Name)
                    {
                        case "Entity2Reference":
                            Entity1.Entity2Reference.EntityKey = new EntityKey("MyEntities." + entityName + "s", prop, val);
                            break;
                        case "Entity3Reference":
                            Entity1.Entity3Reference.EntityKey = new EntityKey("MyEntities." + entityName + "s", prop, val);
                            break;
                        case "Entity4Reference":
                            Entity1.Entity4Reference.EntityKey = new EntityKey("MyEntities." + entityName + "s", prop, Int64.Parse(val));
                            break;
                    }
                }
            }
        }
    }
}

相关内容

  • 没有找到相关文章

最新更新