Найти заданный общий DbSet в DbContext динамически, когда у меня есть объект
У меня есть следующие классы и DbContext
:
public class Order:BaseEntity
{
public Number {get; set;}
}
Product:BaseEntity;
{
public Name {get; set;}
}
public class Context : DbContext
{
....
public DbSet<Order> Orders { set; get; }
public DbSet<Product> Products { set; get; }
....
}
У меня есть список объектов, которые нужно добавить в мой контекст, но я не знаю, как я могу найти соответствующий общий DbSet
по каждому типу объекта динамически.
IList<BaseEntity> list = new List<BaseEntity>();
Order o1 = new Order();
o1.Numner = "Ord1";
list.Add(o1);
Product p1 = new Product();
p1.Name = "Pencil";
list.Add(p1);
Context cntx = new Context();
foreach (BaseEntity entity in list)
{
cntx.Set<?>().Add(entity);
}
Как я могу это сделать?
Ответы
Ответ 1
DbContext
имеет метод, называемый Set
, который вы можете использовать для получения не общего DbSet
, например:
var someDbSet = this.Set(typeof(SomeEntity));
Итак, в вашем случае:
foreach (BaseEntity entity in list)
{
cntx.Set(entity.GetType()).Add(entity);
}
Ответ 2
В дополнение к ответу Пабло:
Вы можете добавить класс в свой проект:
namespace System.Data.Entity
{
public static class EntityFrameworkExtensions
{
public static IEnumerable<object> AsEnumerable(this DbSet set)
{
foreach (var entity in set)
yield return entity;
}
}
}
Этот класс добавляет экземпляр Extention AsEnumerable
to DbSet
и, если вы хотите использовать его, например, для Count или фильтрации некоторой строки:
var someDbSet = this.Set(typeof(SomeEntity));
var count = (from a in someDbSet.AsEnumerable() select a).Count();
Ответ 3
В вопросе не указывается версия EF, и предлагаемый ответ больше не работает для ядра Entity Framework (у DbContext нет нестандартного метода набора в ядре EF, по крайней мере, на дату этого ответа).
Тем не менее, вы все еще можете использовать рабочий метод расширения, используя ответ Jon Skeet на этот вопрос. Мой код добавлен ниже для удобства.
public static IQueryable Set(this DbContext context, Type T)
{
// Get the generic type definition
MethodInfo method = typeof(DbContext).GetMethod(nameof(DbContext.Set), BindingFlags.Public | BindingFlags.Instance);
// Build a method with the specific type argument you're interested in
method = method.MakeGenericMethod(T);
return method.Invoke(context, null) as IQueryable;
}