Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/288.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/asp.net-mvc-3/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 调用泛型方法时,将PropertyInfo用作泛型类型_C#_Entity Framework_Generics_Reflection_System.reflection - Fatal编程技术网

C# 调用泛型方法时,将PropertyInfo用作泛型类型

C# 调用泛型方法时,将PropertyInfo用作泛型类型,c#,entity-framework,generics,reflection,system.reflection,C#,Entity Framework,Generics,Reflection,System.reflection,背景 我正在使用EF,我有很多表。当我插入一个包含导航属性内容但没有id的新实体(我从xls文件中读取内容)时,我不想显式加载所有导航属性。这是太多的代码。所以我尝试了一种通用的方法: private void loadExistingNavigationProperties<TEntity>(TEntity entityToInsert) where TEntity : class { Type type = typeof(TEntity); var propert

背景

我正在使用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)));
        }
    }
}
传递导航属性的当前值。它包含所有信息,如名称或其他信息,但不包含id。首先,我将获取所有具有该类型的可用导航属性。然后我搜索是否有一个属性与当前属性具有相同的属性。然后返回该属性并将其设置为导航属性

编辑:

public List GetAllEntries(),其中tenty:class
{
使用(var dbContext=newinventardbenties(MainWindow.connectionName))
{
返回GetAllEntries(dbContext);
}
}
公共列表GetAllEntries(InventardBenties dbContext),其中tenty:class
{
返回dbContext.Set().ToList();
}
问题


我现在的问题是如何告诉方法
findNavigationProperty
泛型类型就是属性值所具有的类型。因此,将
替换为类型。

您可以检索这样的泛型类型:

var item = propertyInfo.GetGenericArguments()[0];
您可以使用“is”检查它是否为类型

您还可以执行以下操作:

item.BaseType == typeof(Whatever type your navigation props inherit);

正如我在评论中已经提到的:
泛型类型参数在编译时解析
因此,您无法从
System.type
检索泛型类型

问题的关键是使用
System.Type
而不是泛型。
请注意,我没有测试下面的代码,因为我还没有将EF.
安装到我的知识DbContext的
系统中。Type
重载应该可以正常工作

private void loadExistingNavigationProperties(TEntity entityToInsert),其中TEntity:class
{
类型tenty=类型of(tenty);
var properties=tenty.GetProperties()。除了(tenty.GetProperties()。其中(x=>x.Name.Contains(“id”));
foreach(属性中的PropertyInfo属性)
{
if(property.PropertyType.FullName.Contains(“MyNamespace”))
{
object val=findNavigationProperty(property.GetValue(entityToInsert),tenty);
SetValue(entityToInsert,val);
}
}
}
私有对象findNavigationProperty(对象navigationPropertyValue,类型tEntity)
{
DbSet navigationProperties=GetAllEntries(tEntity);
foreach(navigationProperties中的var实体)
{
//您可能会遇到类型问题。
//如果是:转换为正确的类型或更改“PropertiesReequal”。
if(属性相等(实体、导航属性值))
{
返回实体;
}
}
返回navigationPropertyValue;
}
公共数据库集GetAllEntries(tEntity类型)
{
使用(var dbContext=newinventardbenties(MainWindow.connectionName))
{
返回GetAllEntries(dbContext,tEntity);
}
}
公共数据库集GetAllEntries(InventardBenties数据库上下文,类型tEntity)
{
返回dbContext.Set(tenty);
}

您无法在运行时检索泛型类型。泛型类型必须在编译时可解析。如果要将运行时解析的类型传递给方法,必须通过传递反射的
System.type
来实现。
GetAllEntries()
是否有接受
System.Type
参数的重载?@NoelWidmer我添加了GetAllEntries方法。它不接受System.TYPE参数。您是否还有
InventardBenties
的来源?我想它是.NET类型的。在这种情况下,您能告诉我它派生的类名的名称吗。(我想看看是否存在接受
System.Type
而不是泛型参数的
inventardbenties.Set()
重载)泛型和反射不能很好地混合。泛型是编译时构造,而反射是运行时构造。但您可以。@NoelWidmer:InventardBenties源于DbContext。是的,它可以工作。而且它比通过反射调用方法要干净得多。非常感谢。我只是不明白为什么DbSet的方法比DbSet少,但这是另一个问题,强制转换也解决了这个问题。@L3n95酷!我没有经常使用DbSet,因此无法回答这个问题。我总是喜欢泛型类型而不是一般对象类型。但是在使用反射类型的情况下,通常没有更好的选择。
var item = propertyInfo.GetGenericArguments()[0];
item.BaseType == typeof(Whatever type your navigation props inherit);
private void loadExistingNavigationProperties<TEntity>(TEntity entityToInsert) where TEntity : class
{
    Type tEntity = typeof(TEntity);
    var properties = tEntity.GetProperties().Except(tEntity.GetProperties().Where(x => x.Name.Contains("id")));
    foreach (PropertyInfo property in properties)
    {
        if (property.PropertyType.FullName.Contains("MyNamespace"))
        {
            object val = findNavigationProperty(property.GetValue(entityToInsert), tEntity);
            property.SetValue(entityToInsert, val);
        }
    }
}

private object findNavigationProperty(object navigationPropertyValue, Type tEntity)
{
    DbSet navigationProperties = GetAllEntries(tEntity);
    foreach (var entity in navigationProperties)
    {
        // You may get a type issue.
        // If so: cast to the correct type or change "propertiesAreEqual".
        if (propertiesAreEqual(entity, navigationPropertyValue))
        {
            return entity;
        }
    }
    return navigationPropertyValue;
}

public DbSet GetAllEntries(Type tEntity)
{
    using (var dbContext = new InventarDBEntities(MainWindow.connectionName))
    {
        return GetAllEntries(dbContext, tEntity);
    }
}

public DbSet GetAllEntries(InventarDBEntities dbContext, Type tEntity)
{
    return dbContext.Set(tEntity);
}