【问题标题】:How the return type is determined in a method that uses Linq2Sql?在使用 Linq2Sql 的方法中如何确定返回类型?
【发布时间】:2010-03-31 14:08:15
【问题描述】:

在涉及 linq 时,我通常在返回类型方面遇到困难。我将通过以下示例进行解释。假设我有一个表 Products,其中 ProductID、Name、Category 和 Price 作为列:

1) IQueryable>**

public IQueryable<Product> GetChildrenProducts()
{
  return (from pd in db.Products
          where pd.Category == "Children"
          select pd);
}

2) 产品

public Product GetProduct(int id)
{
  return (from pd in db.Products
          where pd.ProductID == id
          select pd).FirstOrDefault();
}

现在,如果我决定选择,例如,只选择一列(价格或名称)或什至 2 或 3 列(名称和价格),但无论如何,少于 4 列,那将是返回类型?

我的意思是:

public returnType GetSomeInformation()
{
 return (from pd in db.Products
         select new { pd.Name, pd.Price }
}

GetSomeInformation()returnType 应该是什么?

感谢您的帮助

【问题讨论】:

    标签: linq-to-sql


    【解决方案1】:

    您不能在这种情况下使用var,因为目前只能在局部变量中推断类型。

    所以要么:

    Select() 部分移动到调用者,并返回一个普通的IQueryable&lt;Product&gt;

    public IQueryable<Product> GetSomeInformation()
    {
      return (from pd in db.Products
              select pd);
    }
    
    var information = GetProductInformation().Select(p => new { p.Name, p.Price });
    

    创建一个仅包含您需要的信息的返回类型 ProductInformation:

    class ProductInformation
    {
      public string Name { get; set; }
      public decimal Price { get; set; }
    }
    
    public IQueryable<ProductInformation> GetSomeInformation()
    {
      return (from pd in db.Products
              select new ProductInformation { Name=pd.Name, Price=pd.Price });
    }
    

    【讨论】:

    • @Yannick M. -- 如果我决定查询 ProductID 和 Category(而不是 Name 和 Price),是否需要创建另一个包含 2 列的类?
    • 如果你愿意,你可以让你的类包含所有四个字段,并且只设置你需要使用的字段,如果你愿意的话。或者,您可以根据为每个 LINQ 请求返回的字段创建多个类。
    • 我更喜欢第一个选项,即只有一个类并设置我想要的字段。如果这是真的,(i)我可以在上面的示例中使用 Product 代替 ProductInformation 吗? (ii0 如果我可以使用 Product 而不是 ProductInformation,我是否需要 'Name = pd.Name' 来代替 'Name'?
    • 另外,从上面的语句“var information = GetProductInformation().Select(p => new { p.Name, p.Price }”中,我如何使用动态查询(字符串)来替换"p => new { p.Name, p.Price" 通过字符串。我该怎么做?
    【解决方案2】:

    如果您选择多个列,但不是整个对象,LINQ 会返回一个通用对象。如果您想通过函数返回该数据子集,则需要创建自己的类并像这样加载它:

    public class MyObject
    {
      public string Name { get; set; }
      public double Price { get; set; }
    }
    
    public MyObject GetSomeInformation()
    {
     return (from pd in db.Products
             select new  MyObject {
               Name = pd.Name, 
               Price = pd.Price 
             }).FirstOrDefault();
    }
    

    【讨论】:

    • @Charles Boyung -- 如果我决定只查询一列(例如,选择 pd.name)怎么样。我需要创建一个属性的类吗?或者我可以使用简单的类型,比如string、int、bool等?
    • 是的,如果您只想要一个列,那么您可以使用该列的任何 .Net 类型。如果您不确定,该列的 VS intellisense 会在您编写代码时告诉您类型。
    【解决方案3】:

    简答:IEnumerable

    长答案:

    您返回的是anonymous type 的集合,因此需要返回类型为IEnumerable

    【讨论】:

    • 您建议如何获取无类型匿名类型的属性值? (不要说反射 ;-)
    • 我只是讨厌在 C# 中缺少动态成员解析的一件事。 VB.NET 自 .NET 1.0 起就有这个功能。真是太棒了。现在每个人都在谈论动态,就像第二次出现一样。哎呀......它已经存在了很长时间。
    • Tbh,我认为 DLR 的实施只是达到目的的一种手段。这让我可以减少烦人的 COM 互操作,并调用动态语言资源。但我不认为自己会在其他方面使用 dynamic 关键字。
    • 在使用动态成员解析的所有原因中,这将是最糟糕的原因之一。不过,如果类型推断算法允许您在不声明类的情况下返回类型化结果,那就太好了。
    • @erikkallen 问题是,Erik,VB 从 Win 3.1 的 VB 3 和 VB.NET 1.0 开始就有这种东西。所有分辨率都是动态完成的。当然,您不能像使用动态类型那样创建新成员,但您可以调用任何您想要的现有成员。
    猜你喜欢
    • 1970-01-01
    • 2010-11-09
    • 1970-01-01
    • 1970-01-01
    • 2021-02-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-01-16
    相关资源
    最近更新 更多