【问题标题】:How to create anonymous object from T?如何从 T 创建匿名对象?
【发布时间】:2019-09-15 14:55:33
【问题描述】:

我在 EF 上下文中有 GetEntities 方法。在某些情况下,我不想在内存中加载实体的所有属性。我只想加载“选定”属性。我使用匿名对象只获取特殊属性。例如,我有 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。在那里,您可以将属性作为集合访问。

标签: c# entity-framework anonymous-methods


【解决方案1】:

您可以使用Repository pattern 处理此问题。

创建Repository class like ;

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();
     }
 }

【讨论】:

    【解决方案2】:

    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> 选择器。我只有字符串集合。看上面的GetEntities方法
    • 如果您的属性名称在字符串中,那么您需要进行反射,因为您需要告诉编译器哪个属性名称与实体属性映射。我认为这样做是一项乏味的任务。我建议您仔细阅读我的回答,因为存储库模式在大多数情况下更加灵活和适用。
    • 会发生什么?你现在遇到什么问题了吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-04-06
    • 1970-01-01
    • 2016-01-30
    • 1970-01-01
    • 2013-09-02
    • 2011-09-17
    • 2014-08-19
    相关资源
    最近更新 更多