ano*_*ous 3 c# linq entity-framework
我有一个方法AddStudent(),它查找具有相同名称的学生,如果有同名学生,则从数据库返回现有学生,否则它会创建一个新学生并将其添加到数据库中.
我很好奇为什么当我尝试从LINQ查询获得第一个结果se = students.First<StudentEntity>();
时se = students.ElementAt<StudentEntity>(0);
失败成功.这两种方法不一样吗?
该方法的完整代码如下所示.
public Student AddStudent(string name)
{
using (SchoolEntities db = new SchoolEntities())
{
// find student with same name via LINQ
var students = from s in db.StudentEntitySet
where s.name == name
select s;
StudentEntity se = default(StudentEntity);
// if student with the same name is already present, return
// that student
if (students.Count<StudentEntity>() > 0)
{
// if i use ElementAt, if fails with a "LINQ to Entities does not
// recognize the method 'StudentEntity ElementAt[StudentEntity]
// (System.Linq.IQueryable`1[StudentEntity], Int32)' method,
// and this method cannot be translated into a store expression.",
// but not when I use First. Why?
// se = students.ElementAt<StudentEntity>(0);
se = students.First<StudentEntity>();
}
else
{
// passing 0 for first parameter (id) since it's represented by
// a BigInt IDENTITY field in the database so any value
// doesn't matter.
se = StudentEntity.CreateStudentEntity(0, name);
db.AddToStudentEntitySet(se);
db.SaveChanges();
}
// create a Student object from the Entity object
return new Student(se);
}
}
Run Code Online (Sandbox Code Playgroud)
谢谢!
它失败是因为该ElementAt
方法是索引访问方法,而实体框架不知道如何将其转换为SQL.
使用该First
方法时,Entity Framework可以将其转换TOP 1
为SQL查询中的子句.这非常简单.为了使用ElementAt
它,它必须构建一个基于窗口函数(ROW_NUMBER()
)的更复杂的查询,而且,它只是不够复杂到那么做.
它实际上是实体框架的文档限制.该ElementAt
扩展名根本不支持.
理论上,你可以这样写:
se = students.AsEnumerable().ElementAt<StudentEntity>(0);
Run Code Online (Sandbox Code Playgroud)
这指示实体框架在AsEnumerable()
调用之后不要尝试"翻译"任何内容,因此它将检索所有结果(而不仅仅是第一个)并迭代它们直到它到达您想要的元素(在这种情况下)只是碰巧是第一个).
然而,这会减慢运行了很多比仅仅使用First()
,因为不是从服务器获取刚刚1分的结果,它获取所有这些和过滤器之后.如果出于某种奇怪的原因,我需要得到第5或10元或某些元素,我只会使用此解决方案的其他比第一个.
归档时间: |
|
查看次数: |
4898 次 |
最近记录: |