如何使用Linq返回带有列的结果集

时间:2011-04-02 14:52:01

标签: linq linq-to-entities intellisense

我在一个类中有一个函数,它将运行Linq to Entities查询(或实际上任何类型的Linq查询),并且它将在结果集中返回2列。我想将一个对象返回到调用我的函数的任何人,这将允许Intellisense知道我返回的内容 让我解释。如果我有这样的功能:

public static IQueryable GetInfo(MyEntityModel oEntityModel)
{
  var query =
    (from t in oEntityModel.Table1
     from u in t.Table2
     where t.Status == true &&
     u.Status == true
     select new
     {
       t.Column1,
       u.Column2
     })
  return query;
}

我可以(应该)放置什么而不是IQueryable,以便无论谁调用我的GetInfo函数,都会从结果集中获取Intellisense,并显示它有一个Column1和Column2?

var linqresult = ClsLinqTeste.GetInfo(oEntityModel);
if (linqresult.Column1 == 1)
{
  foreach (var oItem in linqresult)
  {
    .. do stuff...
  }
}

韩国社交协会

5 个答案:

答案 0 :(得分:3)

您不能从函数返回匿名类型,它们是严格的“内联”类。返回时,foreach循环只能将结果解释为普通对象。我猜你可以使用反射来查询属性名称和值,但是定义数据传输类型以保存结果似乎更直接。

请参阅此question和此blog post

所以你可以创建一个简单的结构或类:

public class MyDataResult
{
    public object Column1 { get; set; }
    public object Column2 { get; set; }
}

然后在函数中修改您的查询:

public static IQueryable<MyDataResult> GetInfo(MyEntityModel oEntityModel)
{
  var query =
    (from t in oEntityModel.Table1
     from u in t.Table2
     where t.Status == true &&
     u.Status == true
     select new MyDataResult
     {
       Column1 = t.Column1,
       Column2 = u.Column2
     })
  return query;
}

这样的事情应该有用。请注意,我在MyDataResult中使用了“object”作为属性。我不知道你要返回的列的类型,你应该使用实际的类型来获得完整的intellisense。

答案 1 :(得分:2)

您正在返回一组匿名类型,它们将被转换为对象,因此当您尝试迭代它们时,尽管它们将是您的对象(并且它们将包含您的属性),但在编译时它们将被转换为对象:

foreach (var x in ClsLinqTeste.GetInfo(oEntityModel))
{
  //x is an Object
}

您可以详细了解here

如果您想要智能感知,我建议您创建一个自定义类,它们将保存您的属性并返回不是匿名类型(使用new {}),而是返回您的类的对象(new MyClass(prop1, prop2))。您还需要更改方法的签名,因此它返回IQueryable<YourClass>而不仅仅是普通的非通用IQueryable

答案 2 :(得分:1)

正如其他人所说,创建一个新类型来保存两列通常是最好的选择。

但是,如果由于某种原因,您不想这样做而且您使用的是.Net 4.0,则可以使用Tuple

public static IQueryable<Tuple<Column1Type, Column2Type>>
    GetInfo(MyEntityModel oEntityModel)
{
  return from …
         select Tuple.Create(t.Column1, u.Column2);
}


var linqresult = ClsLinqTeste.GetInfo(oEntityModel);
foreach (var oItem in linqresult)
  Console.WriteLIne(oItem.Item1, oItem.Item2);

答案 3 :(得分:0)

当您返回结果集AsQueryable时,该应用程序已经能够为您提供智能感知,但是在您的示例中,如果您知道您的集合只有一行,则必须指定.FirstOrDefault,或者迭代您的集合以获取来自它的项目,如下:

这就是你正在做的事情:

var linqresult = ClsLinqTeste.GetInfo(oEntityModel);
if (linqresult.Column1 == 1)
{
  ..do stuff...
}

这是你应该怎么做的:

var linqresult = ClsLinqTeste.GetInfo(oEntityModel);

foreach(var item in linqresult)
{
  if (item.Column1 == 1)
  {
    ..do stuff...
  }
}

你必须遍历linqresult,因为当你使用link查询时,它会返回一个结果集,即使它只有一列。与任何集合一样,您的数据列在整个结果集中不可用,仅适用于单个项目。

答案 4 :(得分:0)

如果您想要强类型枚举非通用IEnumerable(IEnumerable.GetEnumerator()而不是IEnumerable<T>.GetEnumerator<T>()),您可以使用Cast&lt;&gt;()扩展名,就像这样

 var myquery = GetQueryable();

 for (var item in myquery.Cast<MyDataType>())
 {
       // use item.Column1 directly and strongly typed with intellisense
 }