【问题标题】:How to return LINQ object from method?如何从方法返回 LINQ 对象?
【发布时间】:2013-10-08 18:11:59
【问题描述】:

我的方法具有 LINQ 查询和来自多个表的查询返回列。

如何返回该 LINQ 结果对象并在调用方方法迭代结果中捕获它并分配给模型类?

public ??? GetLocation(string CustomerNum)
    {
        if (!string.IsNullOrEmpty(CustomerNum))
        {
            var results = from ca in _context.CUS_ADDRESS
                           join cad in _context.CUS_ADDRESS_DETAIL on ca.CUS_ADDRESS_ID equals cad.CUS_ADDRESS_ID
                          where (cad.PRIORITY_SEQ == 0) && (ca.MASTER_CUSTOMER_ID == CustomerNum)
                           select new
                           {
                               CustomerNumber = ca.MASTER_CUSTOMER_ID,
                               ca.ADDRESS_1,
                               ca.ADDRESS_2,
                               ca.ADDRESS_3,
                               ca.ADDRESS_4,
                               ca.CITY,
                               ca.STATE,
                               ca.COUNTRY_DESCR,
                               cad.ADDRESS_TYPE_CODE,
                               cad.ADDRESS_STATUS_CODE
                           };
            return results;
        }
        else
        {
            return null;
        }
    }

调用方法

var results = Data.GetLocation(CustomerNum)
if (results.Any())
{
   var location = results.FirstOrDefault();
   .....
   .....
 }

GetLocation 返回类型是什么?

【问题讨论】:

  • 目前您正试图返回一个元素类型为匿名类型的序列。您可能想要创建一个 Location 类型来代替您的匿名类型。

标签: c# linq entity-framework


【解决方案1】:

根据您实际使用结果的方式,您可以返回 IQueryable 而不是 IQueryable<T>

我在某些情况下(使用IEnumerable)使用了它,例如具有动态绑定(例如通过Eval 或使用BoundField)的WebForms。

【讨论】:

    【解决方案2】:

    您正在使用select new 创建一个匿名对象,您不能从您的函数返回匿名对象的集合,而是必须创建一个类,该类将具有您的select 语句中的所有属性,然后返回IQueryable<YourClass>

    class YourClass
    {
        public int CustomerNumber { get; set; }
        public string ADDRESS_1 { get; set; }
        //..............
    }
    

    然后:

    var results = from ca in _context.CUS_ADDRESS
                               join cad in _context.CUS_ADDRESS_DETAIL on ca.CUS_ADDRESS_ID equals cad.CUS_ADDRESS_ID
                              where (cad.PRIORITY_SEQ == 0) && (ca.MASTER_CUSTOMER_ID == CustomerNum)
                               select new YourClass
                               {
                                   CustomerNumber = ca.MASTER_CUSTOMER_ID,
                                   ADDRESS_1 = ca.ADDRESS_1,
                                   //...............
    

    并将你的函数返回类型修改为:

    public IQueryable<YourClass> GetLocation(string CustomerNum)
    

    你可以看看这个question for returning IQueryable or Not

    【讨论】:

    • 好像是IQueryable&lt;YourClass&gt;
    • 但是我需要有两个地方的库项目(定义 LINQ)和另一个在调用者项目中的“YouClass”。我只想传递 LINQ 返回的内容,调用者会处理返回值。
    • @KingKong 我做了你在调用者项目中提到的同样的事情。但是现在我们将 LINQ 分离到另一个库项目中,以便它可以重用。
    • @James123 在这种情况下,您可以在调用者项目中使用AutoMapper 之类的工具来自动从库类转换为调用者类。
    • @James123,您可以在一个地方定义YourClass,并从发送者和调用者中引用它,您也可以返回List&lt;Object&gt;,但不要。
    【解决方案3】:

    如果你不想创建一个类,你可以使用元组:

    public IEnumerable<Tuple<int, string, string>> GetCustomer(int custId) { 
        return from p in customers
               where p.Id == custId
               select new Tuple<int, string, string>(
                   p.Id,
                   p.FirstName,
                   p.LastName
               );
    }
    

    虽然这意味着您无法命名他们的字段,因为您访问这样的数据:

    var customer      = GetCustomer(1);
    var custId        = customer.Item1;
    var custFirstName = customer.Item2;
    var custLastName  = customer.Item3;
    

    【讨论】:

      【解决方案4】:

      创建一个将所有列作为属性的自定义助手类。说它的 MyClass。填写如下。我知道这不完全是你想要的,但会帮助你得到你想要的。

      var o= (from c in context.table1
              from d in context.table2
              where c.key=d.key
              select new MyClass
              {
                 Property1=c.abc,
                 Property2=d.xyz
              }).SingleOrDefault();
      

      或者写下你的连接和位置,这样它只会给你单行来自 db。

      【讨论】:

        【解决方案5】:

        在函数中,您正在创建一个匿名对象,因此如果没有一些反射方法,就不能在调用者中使用。但是返回像

        这样的对象会容易得多
        public class CustomerLocation
        {
        public string CustomerNumber {get; set;}
        // and so on
        }
        

        它可以放置在一个公共层中,并由调用者和发送者访问,并显式使用属性。 为此,您的功能最好是

        public IQueryable<CustomerLocation> GetLocation(string CustomerNum)
        {
        // your code here
        }
        

        【讨论】:

          猜你喜欢
          • 2016-01-21
          • 1970-01-01
          • 2022-12-03
          • 1970-01-01
          • 2010-10-02
          • 1970-01-01
          • 1970-01-01
          • 2021-07-21
          相关资源
          最近更新 更多