如何从方法中返回LINQ对象?

5

我有一个方法,其中包含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();
   .....
   .....
 }
< p > GetLocation 函数的返回类型是什么?< /p >

2
目前你正在尝试返回一个元素类型为匿名类型的序列。你可能想创建一个“位置”类型来代替你的匿名类型。 - Jon Skeet
5个回答

3
根据您实际使用结果的方式,您可以返回IQueryable而不是IQueryable<T>。在某些情况下(如WebForms),我已经使用了这种方法(使用IEnumerable),具有动态绑定(通过Eval或使用BoundField等)。

1
您正在使用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)

你可以查看这个关于返回IQueryable还是不返回的问题的讨论

看起来是 IQueryable<YourClass> - King King
1
但是我需要在两个地方使用“YourClass”库项目(其中定义了LINQ),一个是在调用方项目中。我只想传递任何LINQ返回的内容,然后调用方会处理返回值。 - James123
@KingKong,我在调用方项目中也做了同样的事情。但现在我们正在将LINQ分离到另一个库项目中,以便它可以被重复使用。 - James123
@James123 在这种情况下,你可以在调用项目中使用像AutoMapper这样的工具,自动将库类转换为调用类。 - Scott Chamberlain
@James123,你可以在一个地方定义YourClass,并从发送者和调用者引用它。你也可以返回List<Object>,但最好不要这样做。 - Habib

1
如果您不想创建一个类,可以使用元组:
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;

0
创建一个自定义辅助类,将所有列作为属性。假设它的名称为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();

或者编写您的连接和条件语句,以便从数据库中仅获取单行数据。


0
在该函数中,您正在创建一个匿名对象,因此无法在调用方使用它而不需要反射方法。但是,如果返回一个对象,将会更容易。
public class CustomerLocation
{
public string CustomerNumber {get; set;}
// and so on
}

这个函数可以放在公共层中,被调用者和发送者都可以访问,并显式地使用属性。因此,您的函数最好是这样的。

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接