У меня есть метод GetEntities в контексте EF. В некоторых случаях я не хочу загружать в память все свойства сущностей. Я хочу загрузить только «выбранные» свойства. Я использую анонимный объект для получения только специальных свойств. Например, у меня есть объект Product, и я получаю только свойства Name и Cost (ТОЛЬКО ДЛЯ ЧТЕНИЯ).
context.GetEntities<Product>().Select(a => new { a.Name,a.Cost }).ToList();
Я использую его во многих местах. Итак, я создал коллекцию PropertyNames и хочу создать метод GetEntities, который получает сущности со следующими свойствами:
public object GetEntities<T>(IEnumerable<string> proeprtyNames)
{
return //anonymous entities which have only proeprtyNames properties
}
Как создать этот метод? А также я не знаю, какой должен быть возвращаемый тип метода
Я бы не поступил так, как ты собираешься. Однако, чтобы заставить его работать, вы должны заглянуть в System.Reflection. Там вы можете получить доступ к свойствам как к коллекции.





Вы можете использовать Шаблон репозитория для этой проблемы.
Создайте класс Repository как ;
public class Repository<T> where T : class
{
private readonly DbContext _dbContext;
private readonly DbSet<T> _dbSet;
public Repository(DBContext dbContext)
{
_dbContext = dbContext;
_dbSet = dbContext.Set<T>();
}
public IQueryable<T> GetAll()
{
return _dbSet;
}
}
и ваша функция может быть
public object GetEntities<T>()
{
using (DBContext db = new DBContext())
{
Repository<T> repository = new Repository<T>(db);
list = repository.GetAll();
return list.ToList();
}
}
1) Вам необходимо создать репозиторий, чтобы принять ваш TEntity в качестве объекта универсального класса, и в этом репозитории вы должны создать один метод, который может извлекать только те столбцы из таблицы базы данных, которые вы указали в предикате выражения Select.
public class Repository<TEntity> where TEntity : class
{
private readonly DbContext _context;
public Repository(DbContext context)
{
_context = context;
}
public List<TResult> GetEntities<TResult>(Expression<Func<TEntity, TResult>> selector) where TResult : class
{
return _context.Set<TEntity>().Select(selector).ToList();
}
}
2) И затем, используя вышеуказанный репозиторий, вы можете передавать только те свойства из вашего объекта Product, которые вы хотите получить, например
Repository<Product> repository = new Repository<Product>(new MySqlDbContext());
var anonymousResultSet = repository.GetEntities(x => new { x.Name, x.Cost }); //<= Here you can specify those columns that you want to retrieve.
return anonymousResultSet;
Как я могу получить другие сущности?
Не понял, что ты хочешь сказать?
Я не могу использовать селектор Expression<Func<TEntity, TResult>> в параметре. У меня есть только коллекция строк. Посмотрите на метод GetEntities выше
если имена ваших свойств находятся в строках, вам нужно отражение, потому что вам нужно сообщить компилятору, какое имя свойства сопоставляется со свойством сущности. Я думаю, что это утомительная задача. Я предлагаю вам просмотреть мой ответ, потому что шаблон репозитория более гибкий и подходит в большинстве случаев.
Что просходит? Вы столкнулись с какой-либо проблемой сейчас?
Как сказал Майк выше, вам действительно нужно использовать отражение, чтобы работать так, как вы предполагали, потому что компилятор не будет знать о ваших именах свойств строк, а отражение довольно сложно для выполнения вашей работы. Так что попробуйте, как я понял, это действительно полезно, и большинство разработчиков предпочитают этот подход.
Вы не можете определить анонимный тип в качестве возвращаемого типа. Возможно, вы сможете вернуть динамический тип, но это не совсем безопасное программирование типов. Я думаю, вы должны просто написать этот код прямо в своей логике, этот метод на самом деле вас ничего не спасет.