3
 var dbPerson = from p in db.People 
                where p.Id == PersonId select p;
 dbPerson[0].HolidaysRemaining--;

用 dbPerson[0] 向我抛出一个错误,说不能将 [] 索引应用于类型为 'system.linq.lqueryable,holidayBookingApp.model.person> 的表达式

有人可以告诉我如何解决这个问题吗?

谢谢

4

4 回答 4

5

LINQ 查询的结果不是,而是没有索引器List的自定义类型。IQueryable您无法以该形式随机访问 LINQ 查询的结果。

如果您真的需要,您有多种选择:

  • 将其转换为实现的东西IList,例如 call dbPerson.ToList()
  • 如果您真的只需要第一个元素,请IQueryable为此目的使用扩展方法:dbPerson.First()
  • 如果您想要任意元素作为,请为此目的[x]使用扩展方法:IQueryabledbPerson.Skip(x).First()
于 2012-12-14T13:26:06.203 回答
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
于 2012-12-14T13:23:27.203 回答
2

这是因为dbPersonIEnumerable 不支持索引概念。您可以使用一些 Linq 方法,例如dbPerson.First(),或者简单地将其转换为 List:

var list = dbPerson.ToList();
list[0].HolidaysRemaining--;
于 2012-12-14T13:27:25.250 回答
1

您应该了解 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;
        }
于 2012-12-14T13:42:23.317 回答