C# linq语句返回什么类型的对象?
这可能是一个非常愚蠢和明显的问题,但我对Linq很陌生。在我的数据访问层类中,我有以下方法:C# linq语句返回什么类型的对象?,c#,linq,entity-framework,C#,Linq,Entity Framework,这可能是一个非常愚蠢和明显的问题,但我对Linq很陌生。在我的数据访问层类中,我有以下方法: static public ? GetAllUrls() { using (MonitoredUrlsEntities mu = new MonitoredUrlsEntities()) { var query = from urlTbl in mu.UrlLists
static public ? GetAllUrls()
{
using (MonitoredUrlsEntities mu = new MonitoredUrlsEntities())
{
var query = from urlTbl in mu.UrlLists
join histTbl in mu.Histories on
urlTbl.ID equals histTbl.UrlID
select new
{
urlTbl.Url,
urlTbl.UrlTitle,
urlTbl.UrlType,
urlTbl.Frequency,
urlTbl.Active,
urlTbl.LastChangeDate,
urlTbl.LastCheckDate,
histTbl.DateRun,
histTbl.HashValue
};
return query.ToList();
}
这里有一个问号,因为我不知道linq语句返回什么类型的对象。我只是一个可以循环浏览的列表 试试
IEnumerable
如果删除.ToList(),它将是
IQueryable
通常LINQ语句返回一个IEnumerable/IQueryable,因此可以使用.ToList()。在您的例子中,由于.ToList()的原因,您正在返回一个列表
如果删除ToList(),如果您只想在结果中循环您正在使用LINQ表达式中的匿名类型,那么我会将您的返回作为IEnumerable,并且,如文档所述: 不能声明字段、属性、事件或返回类型 指具有匿名类型的方法 好吧,这是一个
列表,其中T
是一种匿名类型,您不能在自己的代码中说出(匿名类型被赋予无法说出的名称)
这是故意这样做的;在本地使用之外传播匿名类型通常是错误的
您应该创建一个具体类型,而不是使用匿名类型。叫它Foo
。然后您的返回类型将是List
它返回匿名类型的列表,并且您不能从方法返回匿名类型(也许如果您使用动态,您可以,但它是混乱的)。不要使用匿名类型,而是创建一个包含所有属性的新类,并将其填充到投影中:
var query = from urlTbl in mu.UrlLists
join histTbl in mu.Histories on
urlTbl.ID equals histTbl.UrlID
select new YourNewType
{
Url = urlTbl.Url,
UrlTitle = urlTbl.UrlTitle,
UrlType = urlTbl.UrlType,
Frequency = urlTbl.Frequency,
Active = urlTbl.Active,
LastChangeDate = urlTbl.LastChangeDate,
LastCheckDate = urlTbl.LastCheckDate,
DateRun = histTbl.DateRun,
HashValue = histTbl.HashValue
};
现在,您的方法可以返回IEnumerable
,它返回IQueryable
,其中T
是查询的选择新建部分中定义的匿名对象
最后,它作为列表返回
方法签名可能应该是:publicstaticlist GetAllUrls()
因为静态公共?GetAllUrls()
似乎无效。在本例中,您返回的是基于类型IQueryable
的匿名对象,因此可以像这样迭代列表
foreach (var item in query)
{
//you could access to each attribute of the object like this
string url = item.Url
string urlTittle = item.UrlTittle
}
无法从方法返回匿名类型(如其他人所说)。创建一个具体类型,然后新建一个。您的返回类型为IEnumerable
,如下所示:
// NOTE: I do not know the actual types of these properties, YMMV
public sealed class UrlHistoryList
{
public string Url { get; set; }
public string UrlTitle { get; set; }
public string UrlType { get; set; }
public int Frequency { get; set; }
public bool Active { get; set; }
public DateTime LastChangeDate { get; set; }
public DateTime LastCheckDate { get; set; }
public DateTime DateRun { get; set; }
public int HashValue { get; set; }
}
static public IEnumerable<UrlHistoryList> GetAllUrls()
{
using (MonitoredUrlsEntities mu = new MonitoredUrlsEntities())
{
var query = from urlTbl in mu.UrlLists
join histTbl in mu.Histories on
urlTbl.ID equals histTbl.UrlID
select new UrlHistoryList
{
Url = urlTbl.Url,
UrlTitle = urlTbl.UrlTitle,
UrlType = urlTbl.UrlType,
Frequency = urlTbl.Frequency,
Active = urlTbl.Active,
LastChangeDate = urlTbl.LastChangeDate,
LastCheckDate = urlTbl.LastCheckDate,
DateRun = histTbl.DateRun,
HashValue = histTbl.HashValue
};
return query.ToList();
}
//注意:我不知道这些属性的实际类型,YMMV
公共密封类UrlHistoryList
{
公共字符串Url{get;set;}
公共字符串UrlTitle{get;set;}
公共字符串UrlType{get;set;}
公共整数频率{get;set;}
公共bool活动{get;set;}
公共日期时间LastChangeDate{get;set;}
公共日期时间LastCheckDate{get;set;}
公共日期时间日期运行{get;set;}
公共int哈希值{get;set;}
}
静态公共IEnumerable GetAllUrls()
{
使用(MonitoredUrlsEntities mu=new MonitoredUrlsEntities())
{
var query=来自mu.urlsists中的urlTbl
加入麻省理工大学历史系
urlTbl.ID等于histTbl.UrlID
选择新的UrlHistoryList
{
Url=urlTbl.Url,
UrlTitle=urlTbl.UrlTitle,
UrlType=urlTbl.UrlType,
频率=urlTbl.频率,
Active=urlTbl.Active,
LastChangeDate=urlTbl.LastChangeDate,
LastCheckDate=urlTbl.LastCheckDate,
DateRun=histTbl.DateRun,
HashValue=histTbl.HashValue
};
返回query.ToList();
}
正如一些答案所指出的,由于该方法的返回类型是匿名类型,因此您在该方法的返回类型上遇到了问题。您可以使用一些技巧来解决这个问题;这些技巧主要涉及在GetAllUrls
的调用站点定义匿名类型,将GetAllUrls
定义为通用方法,并允许剩下的由艾勒的类型推断来完成
不过,在这种情况下,最好确保EF和数据库在URL和历史记录之间定义了关系,并使用EF从每个URL获取历史记录(反之亦然)。例如:
foreach (var url in mu.UrlLists)
foreach (var history in url.Histories)
{
var obj = new {
url.Url,
url.UrlTitle,
url.UrlType,
url.Frequency,
url.Active,
url.LastChangeDate,
url.LastCheckDate,
history.DateRun,
history.HashValue
};
// do something with obj
}
或者只是
foreach (var url in mu.UrlLists)
foreach (var history in url.Histories)
//do something with url and history
正如其他人所指出的,此特定查询的结果涉及匿名类型。因此,您不能将该方法注释为返回局部变量的确切类型,因为您不能键入该类型的名称,因为它没有名称;这就是“匿名”的意思
您可以说该方法返回IEnumerable
或IEnumerable
或object
甚至dynamic
,但最好的做法可能是首先让查询返回一个标称类型的序列。
更一般地说:正如其他人所指出的,在实践中,查询通常具有某种类型的IEnumerable
或IQueryable
类型。但是,重要的是要认识到LINQ表达式不一定具有任何特定类型。LINQ是作为语法转换而不是语义转换实现的。当您说:
var query = from c in customers select c.Name;
编译器盲目地将其转换为:
var query = customers.Select(c=>c.Name);
query
的类型是无论方法Select
恰好返回什么。它可能是int
!它几乎肯定不是,因为那将是愚蠢的,但是如果某个变态的人决定使用名为Select
的方法返回int
,那么查询类型将是int
事实证明,我就是这样一个反常的人;我举了一个使用LINQ来处理整数的例子:
取决于声明