Отражение с использованием дженериков - PullRequest
0 голосов
/ 31 мая 2019

Я хотел бы вернуть свойства серии объектов DbSet, которые я сохранил в классе с помощью отражения, но для доступа к этим данным в одном методе мне нужно было бы передать переменную в качестве средства доступа для возврата свойства этого объекта.

В настоящее время мне удалось вернуть свойства всех объектов DbSet, но код выглядит очень СУХИМ.

public DbSet<Foo> Foo {get;set;}
public DbSet<Bar> Bar {get;set;}

public List<string> GetPropertiesFoo()
{
    DbContext client = new DbContext();
    return client.Foo.GetType().GetProperties().Select(e => e.Name).ToList();
}
public List<string> GetPropertiesBar()
{
    DbContext client = new DbContext();
    return client.Bar.GetType().GetProperties().Select(e => e.Name).ToList();
}

Мое намерение состоит в том, чтобы реорганизовать это так, чтобы оно принимало имя DbSet в качестве аргумента и возвращало один список свойств, а не список всех свойств.

Ответы [ 3 ]

1 голос
/ 31 мая 2019

Вы ищете что-то подобное, чтобы сделать все это одним ударом. Обратите внимание, что этот код довольно многословен, так что каждый шаг может быть объяснен:

// Make the method generic so we can use it on any context
public List<string> GetProperties<TContext>(string dbSetName = "")
    where TContext : DbContext // Make sure we have a Dbcontext
{
    var propertyNames = typeof(TContext)

        // Get all properties of context
        .GetProperties() 

         // Filter out so we only have DbSet<> types
        .Where(pi => pi.PropertyType.IsGenericType &&
                     typeof(DbSet<>).IsAssignableFrom(pi.PropertyType.GetGenericTypeDefinition()))

        // If a DbSet name has been specified, filter it out
        .Where(pi => string.IsNullOrEmpty(dbSetName) || pi.Name == dbSetName)

        // Get the generic type e.g. Foo
        .Select(pi => pi.PropertyType.GetGenericArguments()[0])

        // Get the individual properties of the entity types
        .Select(t => t.GetProperties())

        // Get all of the property names
        .SelectMany(x => x.Select(pi => pi.Name)); 

    return propertyNames.ToList();
}

И используйте это так:

// All properties for all sets
var allProperties = GetProperties<MyContext>();

// Only properties for the Foo set
var fooProperties = GetProperties<MyContext>("Foo");
0 голосов
/ 03 июня 2019
public List<Foo> GetFooFromBar(string bar)
{
     return = typeof(FooContext)//a list of DbSets (DbSet<Foo>, DbSet<Bar>)
    .GetProperties()
    .Where(e => e.Name == bar)//Filter based on the name of DbSet entered
    .GetType()//Get Type of the object returned (the DbSet with a matching name)
    .GetGenericArguments()[0]//Get the first item in the array of PropertyInfo
    .GetProperties()//Get a list of the properties of the DbSet within the Context
    .ToList();
    return bar;
}
0 голосов
/ 31 мая 2019

Я думаю, что вы могли бы после чего-то вроде

public List<string> GetProperties(string model)
{
   var property = 
      this.GetType()
      .GetProperties()
      .Where(p=>p.Name == model)
      .FirstOrDefault();

   if(property == null) return IEnumerable.Empty<string>().ToList();
   return property
      .PropertyType
      .GetGenericArguments()[0]
      .GetProperties()
      .Select(p=>p.Name)
      .ToList();
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...