var dbPerson = from p in db.People
where p.Id == PersonId select p;
dbPerson[0].HolidaysRemaining--;
用 dbPerson[0] 向我抛出一个错误,说不能将 [] 索引应用于类型为 'system.linq.lqueryable,holidayBookingApp.model.person> 的表达式
有人可以告诉我如何解决这个问题吗?
谢谢
var dbPerson = from p in db.People
where p.Id == PersonId select p;
dbPerson[0].HolidaysRemaining--;
用 dbPerson[0] 向我抛出一个错误,说不能将 [] 索引应用于类型为 'system.linq.lqueryable,holidayBookingApp.model.person> 的表达式
有人可以告诉我如何解决这个问题吗?
谢谢
LINQ 查询的结果不是,而是没有索引器List
的自定义类型。IQueryable
您无法以该形式随机访问 LINQ 查询的结果。
如果您真的需要,您有多种选择:
IList
,例如 call dbPerson.ToList()
。IQueryable
为此目的使用扩展方法:dbPerson.First()
[x]
使用扩展方法:IQueryable
dbPerson.Skip(x).First()
要获取查询dbPerson
返回的第一项,请使用
var firstPerson = dbPerson.First();
或者Single
,如果您只期望一场比赛,并且希望在这种期望被打破时抛出异常。
但是,我不相信firstPerson.HolidaysRemaining--;
会在没有进一步代码的情况下更改数据库中的任何内容:
var dbPeopleWithThisId = from p in db.People
where p.Id == PersonId
select p;
var specificPerson = dbPeopleWithThisId.Single();
specificPerson.HolidaysRemaining--;
db.SaveChanges(); // Thanks to J. Steen
这是因为dbPerson
IEnumerable 不支持索引概念。您可以使用一些 Linq 方法,例如dbPerson.First()
,或者简单地将其转换为 List:
var list = dbPerson.ToList();
list[0].HolidaysRemaining--;
您应该了解 Linq & IEnumerable (& IQueryable) 接口背后的想法。IEnumerable 用于延迟加载序列,因此如果您为循环创建扩展方法,如下所示:
public static IEnumerable<T> LazyForEach<T>(this IEnumerable<T> source, Action<T> action) //action to perform
{
if (action == null) throw new ArgumentNullException("action");
foreach (T element in source)
{
action(element);
yield return element;
}
}
并尝试在 IEnumerable-returning 方法(Linq)链中使用 LazyForEach:
db.People.Where(p=>p...).LazyForEach(p=>
{
MessageBox.Show(p.ToString());
});
在您使用 ToList/ToArray/ElementAt/First/Last/Any/Take/Skip ... 强制枚举(可能是部分)之前,您在提供的操作中的代码不会执行,或者您可以创建 alt. 延期:
public static IEnumerable<T> ForEach<T>(this IEnumerable<T> source, Action<T> action)
{
if (source == null)
return null;
if (action == null) throw new ArgumentNullException("action");
//var sourceList = source.ToList(); //forcing enumeration
var sourceList = new List<T>();
foreach (var element in source)
{
action(element);
sourceList.Add(element);
}
return sourceList;
}