【发布时间】:2017-05-05 09:33:13
【问题描述】:
背景
我正在使用 EF,我有很多表。当我插入具有导航属性内容但没有 id 的新实体时(我正在从 xls 文件中读取内容),我不想显式加载所有导航属性。这是太多的代码。所以我尝试了一种通用的方式:
private void loadExistingNavigationProperties<TEntity>(TEntity entityToInsert) where TEntity : class
{
Type type = typeof(TEntity);
var properties = type.GetProperties().Except(type.GetProperties().Where(x => x.Name.Contains("id")));
foreach (PropertyInfo property in properties)
{
if (property.PropertyType.FullName.Contains("MyNamespace"))
{
property.SetValue(entityToInsert, findNavigationProperty<???>(property.GetValue(entityToInsert)));
}
}
}
我有我的entityToInsert。如果它具有导航属性 (contains("MyNamespace")),我会检查它的所有属性。如果这是真的,导航属性应该被加载(见下文)并设置。
private object findNavigationProperty<TNavigationProperty>(TNavigationProperty navigationPropertyValue) where TNavigationProperty : class
{
List<TNavigationProperty> navigationProperties = GetAllEntries<TNavigationProperty>();
foreach (var entity in navigationProperties)
{
if (propertiesAreEqual(entity, navigationPropertyValue))
{
return entity;
}
}
return navigationPropertyValue;
}
传递了导航属性属性的当前值。它包含所有信息,例如名称或其他信息,但不包含 id。首先,我得到所有具有该类型的可用导航属性。然后我正在搜索是否有一个属性与当前属性相同。然后这个返回并设置为导航属性。
编辑:
public List<TEntity> GetAllEntries<TEntity>() where TEntity : class
{
using (var dbContext = new InventarDBEntities(MainWindow.connectionName))
{
return GetAllEntries<TEntity>(dbContext);
}
}
public List<TEntity> GetAllEntries<TEntity>(InventarDBEntities dbContext) where TEntity : class
{
return dbContext.Set<TEntity>().ToList();
}
问题
我现在的问题是如何告诉方法findNavigationProperty 泛型类型是属性值所具有的类型。所以用类型替换???。
【问题讨论】:
-
您无法在运行时检索泛型类型。泛型类型在编译时必须是可解析的。如果要将运行时解析的类型传递给方法,则必须通过传递反射的
System.Type来实现。GetAllEntries()是否有接受System.Type参数的重载? -
@NoelWidmer 我添加了 GetAllEntries 方法。它不接受 System.Type 的参数
-
你也有
InventarDBEntities的来源吗?我想它是一种 .NET 类型。在那种情况下,你能告诉我它派生的类名的名称吗? (我想看看是否存在接受System.Type而不是泛型参数的InventarDBEntities.Set()重载) -
泛型和反射不能很好地混合。泛型是一个编译时结构,而反射是一个运行时结构。不过,您可以 construct a generic method call at runtime。
-
@NoelWidmer:InventarDBEntities 派生自 DbContext。
标签: c# entity-framework generics reflection system.reflection