簡體   English   中英

從LINQ查詢中獲取第一個結果 - 為什么是ElementAt <T> (0)在第一時失敗 <T> ()成功了嗎?

[英]Getting the first result from a LINQ query - why does ElementAt<T>(0) fails when First<T>() succeeds?

我有一個方法AddStudent() ,它查找具有相同名稱的學生,如果有同名學生,則從數據庫返回現有學生,否則它會創建一個新學生並將其添加到數據庫中。

我很好奇為什么se = students.First<StudentEntity>(); se = students.ElementAt<StudentEntity>(0); 當我嘗試從LINQ查詢中獲取第一個結果時失敗。 這兩種方法不一樣嗎?

該方法的完整代碼如下所示。

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);
    }
}

謝謝!

它失敗是因為ElementAt方法是索引訪問方法,而實體框架不知道如何將其轉換為SQL。

當您使用First方法時,Entity Framework可以將其轉換為SQL查詢中的TOP 1子句。 這非常簡單。 為了使用ElementAt ,它必須基於窗口函數( ROW_NUMBER() )構造一個更復雜的查詢,而且,它只是不夠復雜,不足以做到這一點。

它實際上是實體框架的文檔限制 不支持ElementAt擴展。


理論上,你可以這樣寫:

se = students.AsEnumerable().ElementAt<StudentEntity>(0);

這指示實體框架在AsEnumerable()調用之后不要嘗試“翻譯”任何內容,因此它將檢索所有結果(不僅僅是第一個)並迭代它們直到它到達你想要的元素(在這種情況下恰好是第一個)。

然而,這將減緩操作的大量相比,只用First()因為不是從服務器獲取剛剛1分的結果,它獲取所有這些和過濾器之后。 如果出於某種奇怪的原因,我需要得到第5或10元或比第一個其他的一些因素,我只會使用此解決方法。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM