我在一个类中有一个函数,它将运行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...
}
}
韩国社交协会
答案 0 :(得分:3)
您不能从函数返回匿名类型,它们是严格的“内联”类。返回时,foreach循环只能将结果解释为普通对象。我猜你可以使用反射来查询属性名称和值,但是定义数据传输类型以保存结果似乎更直接。
所以你可以创建一个简单的结构或类:
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
}