【问题标题】:How to return a list of anonymous object in Linq to Sql on joining two tables如何在连接两个表时返回 Linq to Sql 中的匿名对象列表
【发布时间】:2014-09-18 10:43:46
【问题描述】:

我有一个要求,我必须对两个表执行连接并使用 Linq to Sql 返回返回行的列表。

public List<T> GetProductList()
{
    var popupList = (from p in this.Products
                     join c in this.Categories 
                     on p.CategoryID equals c.CategoryID
                     select new
                     {
                         ProductID = p.ProductID,
                         ProductName= p. ProductName,
                         CategoryID = c.CategoryID,
                         CategoryName = c.CategoryName,
                         DateCreated = p.DateCreated,
                         IsActive = p.IsActive
                     }).OrderBy(p => p.CategoryName);

    return popupList;
}

有没有办法在 C# 中做到这一点?

【问题讨论】:

  • dynamic替换T
  • 但是你为什么要匿名呢?为什么不直接创建一个 POCO?
  • 并在末尾添加一个 ToList()。

标签: c# sql linq join anonymous-types


【解决方案1】:

您可以声明一个类,如下所示 -:

public class ProductCategoryView
{
    public int ProductID        { get; set; }
    public strig ProductName    { get; set; }
    public int CategoryID       { get; set; }
    public string CategoryName  { get; set; }
    public DateTime DateCreated { get; set; }
    public bool IsActive        { get; set; }
}

它将具有您希望连接的每一行的值作为属性。

注意我为您的某些属性选择的类型可能有误。所以你必须相应地纠正它们。

然后你必须重构你的查询:

public List<ProductCategoryView> GetProductList()
{
    var popupList = (from p in this.Products
                     join c in this.Categories 
                     on p.CategoryID equals c.CategoryID
                     select new JoinView
                     {
                         ProductID = p.ProductID,
                         ProductName= p. ProductName,
                         CategoryID = c.CategoryID,
                         CategoryName = c.CategoryName,
                         DateCreated = p.DateCreated,
                         IsActive = p.IsActive
                     }).OrderBy(p => p.CategoryName)
                       .ToList();
    return popupList;
}

【讨论】:

  • 我早就想到了,但我担心每次我有这样的需求时是否会导致创建一个新的 POCO 实体。难道没有一种通用的方法可以在不创建新实体类型的情况下返回匿名实体列表吗?
  • 这是一个很好的做法,因为您将拥有所需的视图。我的意思是这是一个明确的设计决定,至少对我来说:)。如果你不喜欢这个,你使用动态。如果不清楚,我可以稍后重新编辑我的帖子。
  • 嗨@Christos,你提出的答案很清楚。但是,我还找到了一种使用 IQueryable 返回类型的方法。您能否建议我使用 IQueryable 作为匿名类型的返回类型的优缺点。
【解决方案2】:

我还找到了一种使用IQueryable 返回类型的方法。您能否建议我使用IQueryable 作为匿名类型的返回类型的优缺点。

public IQueryable GetProductList()
{
    var popupList = from p in this.Products
                     join c in this.Categories 
                     on p.CategoryID equals c.CategoryID
                     select new
                     {
                         ProductID = p.ProductID,
                         ProductName= p. ProductName,
                         CategoryID = c.CategoryID,
                         CategoryName = c.CategoryName,
                         DateCreated = p.DateCreated,
                         IsActive = p.IsActive
                     };
    return popupList.OrderBy(p => p.CategoryName);
}

【讨论】:

  • 不要认为它会编译,因为List&lt;T&gt; 没有实现IQueryable(除非你想在返回语句中调用AsQueryable())。无论如何,为什么 IQueryable 超过 IEnumerable ?要回答您的问题,您会丢失类型信息。由于您返回一个匿名对象,因此您实际上无法转换返回的对象。只剩下dynamic 类型,您不妨返回dynamic 的列表。总而言之,创建 POCO 是该方法的所有使用者更安全、更清晰的途径。
  • 你说得对@SimonBelanger,实际上我没有在我的代码中使用 OrderBy 和 ToList,我也将它从我的帖子中删除了。
猜你喜欢
  • 2015-11-15
  • 2011-07-20
  • 2011-05-21
  • 1970-01-01
  • 2017-09-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多