ไม่สามารถแปลวิธีการเป็นนิพจน์ร้านค้า


89

ฉันเห็นรหัสนี้ทำงานกับ LINQ ถึง SQL แต่เมื่อฉันใช้ Entity Framework มันแสดงข้อผิดพลาดนี้:

LINQ เป็นเอนทิตีไม่รู้จักเมธอด 'System.Linq.IQueryable'1 [MyProject.Models.CommunityFeatures] GetCommunityFeatures ()' เมธอดและเมธอดนี้ไม่สามารถแปลเป็นนิพจน์ร้านค้าได้

รหัสที่เก็บคือ:

public IQueryable<Models.Estate> GetEstates()
{
    return from e in entity.Estates
           let AllCommFeat = GetCommunityFeatures()
           let AllHomeFeat = GetHomeFeatures()
           select new Models.Estate
                      {
                                EstateId = e.EstateId,
                                AllHomeFeatures = new LazyList<HomeFeatures>(AllHomeFeat),
                                AllCommunityFeatures = new LazyList<CommunityFeatures>(AllCommFeat)
                      };
}

public IQueryable<Models.CommunityFeatures> GetCommunityFeatures()
{
    return from f in entity.CommunityFeatures
           select new CommunityFeatures
                      {
                          Name = f.CommunityFeature1,
                          CommunityFeatureId = f.CommunityFeatureId
                      };
}

public IQueryable<Models.HomeFeatures> GetHomeFeatures()
{
    return from f in entity.HomeFeatures
           select new HomeFeatures()
           {
               Name = f.HomeFeature1,
               HomeFeatureId = f.HomeFeatureId
           };
}

LazyList คือรายการที่ขยายพลังของ IQueryable

มีใครสามารถอธิบายได้ว่าเหตุใดจึงเกิดข้อผิดพลาดนี้

คำตอบ:


115

เหตุผล: ตามการออกแบบLINQ to Entitiesต้องการให้นิพจน์แบบสอบถาม LINQ ทั้งหมดถูกแปลเป็นแบบสอบถามเซิร์ฟเวอร์ นิพจน์ย่อยที่ไม่เกี่ยวข้องเพียงไม่กี่นิพจน์ (นิพจน์ในแบบสอบถามที่ไม่ขึ้นอยู่กับผลลัพธ์จากเซิร์ฟเวอร์) จะได้รับการประเมินบนไคลเอ็นต์ก่อนที่จะแปลแบบสอบถาม ไม่รองรับการเรียกใช้เมธอดตามอำเภอใจที่ไม่มีการแปลที่เป็นที่รู้จักเช่น GetHomeFeatures () ในกรณีนี้
เพื่อให้เฉพาะเจาะจงมากขึ้น LINQ to Entities รองรับเฉพาะตัวสร้างและตัวเริ่มต้นแบบไม่มีพารามิเตอร์เท่านั้น

วิธีแก้ไข: ดังนั้นเพื่อให้ได้ข้อยกเว้นนี้คุณต้องรวมแบบสอบถามย่อยของคุณเข้ากับแบบสอบถามหลักสำหรับGetCommunityFeatures ()และGetHomeFeatures ()แทนที่จะเรียกใช้วิธีการโดยตรงจากภายในแบบสอบถาม LINQ นอกจากนี้ยังมีปัญหาในบรรทัดที่คุณกำลังพยายามที่จะยกตัวอย่างตัวอย่างใหม่ของLazyListใช้ก่อสร้างแปรของตนเช่นเดียวกับที่คุณอาจได้รับการทำในLINQ กับ SQL สำหรับวิธีการแก้ปัญหานั้นจะเปลี่ยนไปใช้การประเมินไคลเอนต์ของการสืบค้น LINQ (LINQ เป็น Objects) สิ่งนี้จะทำให้คุณต้องเรียกใช้เมธอดAsEnumerableสำหรับการสอบถาม LINQ ของคุณไปยังเอนทิตีก่อนที่จะเรียกตัวสร้าง LazyList

สิ่งนี้ควรใช้งานได้:

public IQueryable<Models.Estate> GetEstates()
{
    return from e in entity.Estates.AsEnumerable()
       let AllCommFeat = from f in entity.CommunityFeatures
                         select new CommunityFeatures {
                             Name = f.CommunityFeature1,
                             CommunityFeatureId = f.CommunityFeatureId
                         },
       let AllHomeFeat = from f in entity.HomeFeatures
                         select new HomeFeatures() {
                             Name = f.HomeFeature1,
                             HomeFeatureId = f.HomeFeatureId
                         },
       select new Models.Estate {
            EstateId = e.EstateId,
            AllHomeFeatures = new LazyList<HomeFeatures>(AllHomeFeat),
            AllCommunityFeatures = new LazyList<CommunityFeatures>(AllCommFeat)
       };
}


ข้อมูลเพิ่มเติม:โปรดดูที่LINQ to Entities สิ่งที่ไม่รองรับ? สำหรับข้อมูลเพิ่มเติม ตรวจสอบLINQ ไปยังเอนทิตีวิธีแก้ปัญหาเกี่ยวกับสิ่งที่ไม่ได้รับการสนับสนุนสำหรับการอภิปรายโดยละเอียดเกี่ยวกับโซลูชันที่เป็นไปได้ (ลิงก์ทั้งสองเป็นเวอร์ชันแคชเนื่องจากเว็บไซต์เดิมไม่ทำงาน)

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.