【问题标题】:How to use anonymous type returned from a method [duplicate]如何使用从方法返回的匿名类型[重复]
【发布时间】:2012-04-30 06:52:16
【问题描述】:

我有一个简单的数据库,我使用了一个 EF 数据模型。

我的表格如下所示:

客户表

  • 客户 ID
  • 客户名称

订单表

  • 订单编号
  • 客户 ID FK
  • 订购日期

我正在使用辅助类来查询我的模型,在这个类中我有以下查询:

public static List<object> GetCustomerOrdersCount()
{
    using (OrdersDbEntities context = new OrdersDbEntities())
    {
        return context.Customers.Select(
            c => new
            {
                CustId = c.CustomerId,
                CustName = c.CustomerName,
                OrdersCount = c.Orders.Count
            }).ToList<object>();
    }
}

我可以与此方法一起使用的唯一返回类型是 List&lt;object&gt;

最后我的问题是:我如何使用从这个查询中收到的数据?

我可以读取值的唯一方法是通过反射:

List<object> custs = Dal.GetCustomerOrdersCount();

foreach (var customer in custs)
{
   var properties = customer.GetType().GetProperties();

   foreach (var data in properties)
   {
      var value = data.GetValue(custs[0], null);
   }
}

我想知道是否有更好的方法来做到这一点。

【问题讨论】:

  • 你为什么使用对象而不是客户?我假设 context.Customers 是 Customer 的 DbSet?
  • 这是我在尝试返回 List 时遇到的错误:System.Linq.IQueryable' 不包含 'ToList' 的定义和最佳扩展方法重载' System.Linq.ParallelEnumerable.ToList(System.Linq.ParallelQuery)' 有一些无效参数
  • 请发布 OrdersDbEntities 的代码

标签: c# linq entity-framework


【解决方案1】:

我看到的问题是你选择了匿名类型,你不能这样做吗:

public static List<object> GetCustomerOrdersCount()
{
        using (OrdersDbEntities context = new OrdersDbEntities())
        {
            return context.Customers.Select().ToList<Customer>();
        }
}

这将返回您的完整 Customer 实体,而不是只包含特定成员的匿名类型。

编辑

如果就我们关于延迟加载的谈话而言,潜在问题是您想要计算给定客户的订单数量,而不实际加载订单,那么我会这样做:

public class CustomerWithOrderCount
{
    public CustomerWithOrderCount(Customer c, int OrderCount) 
    { 
        Customer = c; 
        this.OrderCount = OrderCount;
    }
    public Customer { get; set; }
    public int OrderCount { get; set; }
}

public static List<object> GetCustomerOrdersCount()
{
        using (OrdersDbEntities context = new OrdersDbEntities())
        {
            return context.Customers.Select(
                c => new CustomerWithOrderCount(c, c.Orders.Count())
                             .ToList();
        }
}

【讨论】:

  • 这是我在尝试执行您的建议时遇到的错误:ObjectContext 实例已被释放,不能再用于需要连接的操作。我想我可以这样做: return context.Customers.Include("Orders").ToList();但这会带来很多不必要的数据...
  • 是的,您可能正在尝试延迟加载。如果你想这样做,你需要保持用于加载实体的上下文,以便实体可以使用上下文从数据库中获取数据。否则使用.Include().LoadProperty() 来加载额外的数据是最好的方法。
  • 或者我可以继续使用反射:) 我会尝试查找你提到的这个延迟加载的东西
【解决方案2】:
public class MiniCustomerDto
{
  public int CustomerId{get;set;}
  public String CustomerName{get;set;}
  public int OrdersCount{get;set;}
}

public static List<MiniCustomerDto> GetCustomerOrdersCount()
{
        using (OrdersDbEntities context = new OrdersDbEntities())
        {
            return context.Customers.Select(c => new MiniCustomerDto
            {
                CustId = c.CustomerId,
                CustName = c.CustomerName,
                OrdersCount = c.Orders.Count
            }).ToList();
        }
}

你必须使用类你不能创建一个返回匿名类型的方法
abd 这是最佳实践检查,
Is there a way to return Anonymous Type from method?
Return anonymous type results?
顺便说一下 Dto 代表数据传输对象

【讨论】:

    【解决方案3】:
     List<tbl_GameConfig> gameConfig = new List<tbl_GameConfig>();
     using (Entities con = new Entities())
      {
           gameConfig = con.tbl_GameConfig.Where(p => p.fk_GameTypeId == gameTypeId).ToList<tbl_GameConfig>();
      }       
    

    【讨论】:

      猜你喜欢
      • 2010-09-08
      • 2010-12-06
      • 1970-01-01
      • 2011-03-10
      • 2019-05-04
      • 1970-01-01
      • 2010-11-22
      • 2020-03-14
      • 1970-01-01
      相关资源
      最近更新 更多