var dbPerson = from p in db.People
where p.Id == PersonId select p;
dbPerson[0].HolidaysRemaining--;
给我一个错误,dbPerson [0]说不能将带有[]的索引应用于类型为'system.linq.lqueryable,holidayBookingApp.model.person>
的表达式有人可以告诉我如何解决这个问题吗?
由于
答案 0 :(得分:5)
您的LINQ查询的结果不是List
,它是一个没有索引器的自定义类型IQueryable
。您无法随机访问该表单中的LINQ查询结果。
如果你真的需要,你有多种选择:
IList
的内容,例如致电dbPerson.ToList()
。 IQueryable
扩展方法实现此目的:dbPerson.First()
[x]
,请使用IQueryable
扩展方法实现此目的:dbPerson.Skip(x).First()
答案 1 :(得分:4)
要获取查询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
答案 2 :(得分:2)
这是因为dbPerson
是IEnumerable,它不支持索引概念。您可以使用一些Linq方法,例如dbPerson.First()
,或者只是将其转换为List:
var list = dbPerson.ToList();
list[0].HolidaysRemaining--;
答案 3 :(得分:1)
你应该理解Linq& amp; 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;
}