1

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

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

在迭代Entity1的Properties时,不知道如何构造一个对Entity2-4的动态查询,并将Entity1.association设置为对应的实体。这是我到目前为止的代码:

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。

我的基本模型:

实体1

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

实体2

Entity2.ID
Entity2.Name

实体3

Entity3.ID
Entity3.Name

实体4

Entity4.ID
Entity4.Name
4

2 回答 2

3

我们就如何metadata摆脱DbContext. 这里有一些链接可以帮助您入门。我将添加一些具体的评论。

如何以编程方式读取 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如果你需要它是完全动态的,你也可以从 a 构造它,例如......
(我一直想这样做:)

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 模型中计算?
获取模型架构以使用不支持
EF5 Code First 迁移中的 CreateDatabase 编程数据转换的提供程序以编程方式创建数据库

于 2013-04-10T21:56:40.353 回答
0

因此,我无法动态执行此操作。但这是我的工作解决方案。谁能建议如何动态执行此操作?

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;
                    }
                }
            }
        }
    }
}
于 2013-04-16T18:16:00.900 回答