我知道这个标题不是最好的,但这是我真正想要完成的。
我有一个表示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;
}
}
}
}
}
}