ไม่สามารถสร้างเอนทิตีได้ในการสืบค้น LINQ to Entities


389

มีชนิดเอนทิตีที่เรียกว่าผลิตภัณฑ์ที่สร้างขึ้นโดยกรอบงานเอนทิตี ฉันเขียนแบบสอบถามนี้

public IQueryable<Product> GetProducts(int categoryID)
{
    return from p in db.Products
           where p.CategoryID== categoryID
           select new Product { Name = p.Name};
}

รหัสด้านล่างพ่นข้อผิดพลาดต่อไปนี้:

"เอนทิตีหรือร้านค้าประเภทที่ซับซ้อนไม่สามารถสร้างสินค้าในแบบสอบถาม LINQ ไปยังเอนทิตี"

var products = productRepository.GetProducts(1).Tolist();

แต่เมื่อฉันใช้select pแทนselect new Product { Name = p.Name};มันทำงานได้อย่างถูกต้อง

ฉันจะ preform ส่วนเลือกที่กำหนดเองได้อย่างไร


System.NotSupportedException: 'เอนทิตีหรือประเภทที่ซับซ้อน' StudentInfoAjax.Models.Student 'ไม่สามารถสร้างได้ใน LINQ ไปยังเอนทิตี'
Md Wahid

คำตอบ:


390

คุณไม่สามารถ (และไม่ควร) โครงการไปยังเอนทิตีที่แมป อย่างไรก็ตามคุณสามารถโปรเจกต์ประเภทที่ไม่ระบุชื่อหรือลงในDTO :

public class ProductDTO
{
    public string Name { get; set; }
    // Other field you may need from the Product entity
}

และวิธีการของคุณจะส่งคืนรายการของ DTO

public List<ProductDTO> GetProducts(int categoryID)
{
    return (from p in db.Products
            where p.CategoryID == categoryID
            select new ProductDTO { Name = p.Name }).ToList();
}

152
ผมไม่เข้าใจว่าทำไมฉันไม่ควรจะสามารถทำเช่นนี้ ... นี้จะเป็นประโยชน์มาก ...
Jonx

118
เอนทิตีที่แมปใน EF นั้นเป็นตัวแทนของตารางฐานข้อมูล ถ้าคุณฉายลงบนเอนทิตีที่แมปสิ่งที่คุณทำโดยทั่วไปคือโหลดเอนทิตีบางส่วนซึ่งไม่ใช่สถานะที่ถูกต้อง EF จะไม่มีเงื่อนงำใด ๆ เช่นการจัดการการปรับปรุงของเอนทิตี้ดังกล่าวในอนาคต (พฤติกรรมเริ่มต้นอาจจะเขียนทับเขตข้อมูลที่ไม่โหลดด้วยค่า Null หรืออะไรก็ตามที่คุณมีในวัตถุของคุณ) นี่จะเป็นการดำเนินการที่อันตรายเนื่องจากคุณอาจเสี่ยงต่อการสูญเสียข้อมูลบางส่วนในฐานข้อมูลดังนั้นจึงไม่อนุญาตให้โหลดเอนทิตีบางส่วน (หรือโครงการไปยังเอนทิตีที่แมป) ใน EF
Yakimych

26
@Yakimych ที่เหมาะสมยกเว้นถ้าคุณมีเอนทิตีรวมบางอย่างที่คุณกำลังสร้าง / สร้างผ่านการสืบค้นดังนั้นจึงมีความตระหนัก / ตั้งใจที่จะสร้างเอนทิตีใหม่เอี่ยมที่คุณจะจัดการและเพิ่มในภายหลัง ในกรณีนี้คุณต้องบังคับให้เรียกใช้คิวรีหรือผลักดันไปยัง dto และกลับไปที่เอนทิตีเพื่อเพิ่ม - ซึ่งเป็นที่น่าผิดหวัง
Cargowire

16
@Cargowire - ฉันเห็นด้วยว่ามีสถานการณ์และน่าผิดหวังเมื่อคุณรู้ว่าคุณกำลังทำอะไร แต่ไม่ได้รับอนุญาตให้ทำเนื่องจากข้อ จำกัด อย่างไรก็ตามหากได้รับอนุญาตก็จะมีนักพัฒนาจำนวนมากผิดหวังที่บ่นว่าข้อมูลของพวกเขาหายไปเมื่อพยายามบันทึกเอนทิตีที่โหลดบางส่วน IMO ข้อผิดพลาดที่ทำให้เกิดเสียงดัง (การยกเว้น ฯลฯ ) นั้นดีกว่าพฤติกรรมซึ่งอาจทำให้เกิดข้อบกพร่องที่ซ่อนอยู่ซึ่งยากต่อการติดตามและอธิบาย (สิ่งที่ชนิดของการทำงานเป็นอย่างดีก่อนที่คุณจะเริ่มสังเกตเห็นข้อมูลที่หายไป)
Yakimych


275

คุณสามารถฉายภาพเป็นแบบไม่ระบุชื่อจากนั้นเป็นแบบจำลองได้

public IEnumerable<Product> GetProducts(int categoryID)
{
    return (from p in Context.Set<Product>()
            where p.CategoryID == categoryID
            select new { Name = p.Name }).ToList()
           .Select(x => new Product { Name = x.Name });
}

แก้ไข : ฉันจะเจาะจงมากขึ้นเนื่องจากคำถามนี้ได้รับความสนใจมาก

คุณไม่สามารถฉายภาพเป็นแบบจำลองโดยตรง (ข้อ จำกัด ของ EF) ดังนั้นจึงไม่มีวิธีแก้ไข วิธีเดียวที่จะฉายภาพในแบบไม่ระบุชื่อ (การวนซ้ำครั้งที่ 1) จากนั้นให้พิมพ์แบบจำลอง (การวนซ้ำครั้งที่ 2)

โปรดทราบว่าเมื่อคุณโหลดเอนทิตีบางส่วนในลักษณะนี้พวกเขาไม่สามารถอัปเดตดังนั้นพวกเขาควรจะยังคงถูกแยกออกเหมือนพวกเขา

ฉันไม่เคยเข้าใจอย่างถ่องแท้ว่าเหตุใดจึงเป็นไปไม่ได้และคำตอบในกระทู้นี้ไม่ได้ให้เหตุผลที่ชัดเจน (ส่วนใหญ่พูดถึงข้อมูลที่โหลดบางส่วน) เป็นความถูกต้องที่ไม่สามารถอัปเดตเอนทิตีในสถานะที่โหลดบางส่วนได้ แต่จากนั้นเอนทิตีนี้จะถูกถอดออกดังนั้นความพยายามในการบันทึกโดยไม่ตั้งใจจะไม่สามารถทำได้

พิจารณาวิธีที่ฉันใช้ด้านบน: เรายังคงมีเอนทิตีโมเดลที่โหลดบางส่วนเป็นผลลัพธ์ เอนทิตีนี้ถูกถอดออก

พิจารณารหัสที่เป็นไปได้นี้ (ต้องการอยู่):

return (from p in Context.Set<Product>()
        where p.CategoryID == categoryID
        select new Product { Name = p.Name }).AsNoTracking().ToList();

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


3
นี่เป็นโซลูชั่นที่สะอาดที่สุดเมื่อคุณไม่ต้องการ / ไม่สนใจสถานะของเอนทิตีที่เลือกที่คุณต้องการฉาย
Mário Meyrelles

2
และเมื่อคุณไม่สนใจว่าคุณกลับ IEnumerable หรือ IQueryable;) แต่คุณก็ยังได้ upvote ของฉันเพราะวิธีนี้ใช้ได้ผลกับฉัน
Michael Brennt

10
ในทางเทคนิคการคาดการณ์ชนิดของแบบจำลองเกิดขึ้นนอกเคียวรีและฉันเชื่อว่าต้องมีการวนซ้ำเพิ่มเติมผ่านรายการ ฉันจะไม่ใช้โซลูชันนี้สำหรับรหัสของฉัน แต่เป็นวิธีแก้ปัญหาสำหรับคำถาม uptick
1c1cle

4
ฉันชอบสิ่งนี้กับโซลูชัน DTO ที่ได้รับการยอมรับ - สวยงามกว่าและสะอาดกว่ามาก
อดัมเฮ้

7
ยกเว้นว่าด้วยความเคารพไม่ใช่คำตอบสำหรับคำถาม นี่เป็นคำตอบสำหรับวิธีการทำโปรเจ็กต์ Linq To Objects ไม่ใช่การฉายเคียวรี Linq to Entities ดังนั้นตัวเลือก DTO เป็นตัวเลือกเดียวเท่านั้น: Linq to Entities
rism

78

มีอีกวิธีหนึ่งที่ฉันพบว่าทำงานได้คุณต้องสร้างคลาสที่มาจากคลาสผลิตภัณฑ์ของคุณและใช้มัน ตัวอย่างเช่น

public class PseudoProduct : Product { }

public IQueryable<Product> GetProducts(int categoryID)
{
    return from p in db.Products
           where p.CategoryID== categoryID
           select new PseudoProduct() { Name = p.Name};
}

ไม่แน่ใจว่านี่เป็น "อนุญาต" แต่ใช้งานได้หรือไม่


3
ฉลาด! พยายามตอนนี้และใช้งานได้ ฉันแน่ใจว่ามันจะเผาฉัน
Daniel

5
BTW สิ่งนี้จะกัดคุณหากคุณพยายามยืนยันผลลัพธ์ของ GetProducts () เนื่องจาก EF ไม่พบการแมปสำหรับ PseudoProduct เช่น "System.InvalidOperationException: ไม่พบการแมปและข้อมูลเมตาสำหรับ EntityType 'blah.PseudoProduct'"
sming

4
คำตอบที่ดีที่สุดและเป็นคำตอบเดียวที่ตอบภายในพารามิเตอร์ของคำถาม คำตอบอื่น ๆ ทั้งหมดเปลี่ยนประเภทการส่งคืนหรือดำเนินการ IQueryable ก่อนกำหนดและใช้ linq กับวัตถุ
rdans

2
ตกใจ 100% ใช้งานได้ ... ใน EF 6.1 นี่ใช้งานได้
TravisWhidden

2
@mejobloggs ลองใช้แอตทริบิวต์ [NotMapped] ในคลาสที่ได้รับหรือ .Ignore <T> หากคุณใช้ API ได้อย่างคล่องแคล่ว
Dunc

37

นี่เป็นวิธีหนึ่งในการทำเช่นนี้โดยไม่ต้องประกาศคลาส aditional:

public List<Product> GetProducts(int categoryID)
{
    var query = from p in db.Products
            where p.CategoryID == categoryID
            select new { Name = p.Name };
    var products = query.ToList().Select(r => new Product
    {
        Name = r.Name;
    }).ToList();

    return products;
}

อย่างไรก็ตามสิ่งนี้จะใช้เฉพาะเมื่อคุณต้องการรวมหลายเอนทิตีในเอนทิตีเดียว ฟังก์ชั่นด้านบน (การทำแผนที่ผลิตภัณฑ์อย่างง่าย) ทำดังนี้:

public List<Product> GetProducts(int categoryID)
{
    var query = from p in db.Products
            where p.CategoryID == categoryID
            select p;
    var products = query.ToList();

    return products;
}

23

อีกวิธีง่าย ๆ :)

public IQueryable<Product> GetProducts(int categoryID)
{
    var productList = db.Products
        .Where(p => p.CategoryID == categoryID)
        .Select(item => 
            new Product
            {
                Name = item.Name
            })
        .ToList()
        .AsQueryable(); // actually it's not useful after "ToList()" :D

    return productList;
}

จุดดีฉันเพิ่งเรียนรู้สิ่งที่ IQueryable ด้วยคำตอบที่ดีของคุณ มันคงจะดีถ้าคุณจะอธิบายว่าทำไมมันไม่มีประโยชน์หลังจาก ToList () และเหตุผลก็คือคุณไม่สามารถใช้รายการทั่วไปในการสืบค้น LINQ-to-SQL ดังนั้นหากคุณรู้ว่าคุณจะต้องผลักดันผลลัพธ์ไปยังข้อความค้นหาอื่นโดยผู้โทรแล้วแน่นอนว่ามันสมเหตุสมผลที่จะเป็น IQueryable แต่ถ้าไม่ใช่ ... ถ้าคุณจะใช้มันเป็นรายการทั่วไปหลังจากนั้นให้ใช้ ToList () ภายในเมธอดเพื่อที่คุณจะไม่ได้ทำ ToList () บน IQueryable แต่ละการเรียกใช้เมธอดนี้
PositiveGuy

คุณไม่เป็นไรเพื่อนของฉันฉันแค่เลียนแบบลายเซ็นของคำถามเพราะฉันแปลงมันเป็น Query สามารถ ... ;)
Soren

1
ใช้งานได้ผล productList จะไม่สามารถแก้ไขได้หลังจาก ToList () ฉันจะทำให้แก้ไขได้อย่างไร
doncadavona

หากคุณใส่.ToListในการค้นหาก็จะถูกดำเนินการและดึงข้อมูลจากเซิร์ฟเวอร์แล้วสิ่งที่เป็นจุดที่จะทำให้มันอีกครั้งAsQueryable?
Moshii

1
@Moshii เพียงเพื่อตอบสนองลายเซ็นประเภทวิธีคืน (ตามที่ฉันพูดในคำตอบมันไม่มีประโยชน์อีกต่อไป)
Soren

4

คุณสามารถใช้สิ่งนี้และควรใช้งานได้ -> คุณต้องใช้toListก่อนที่จะสร้างรายการใหม่โดยใช้การเลือก:

db.Products
    .where(x=>x.CategoryID == categoryID).ToList()
    .select(x=>new Product { Name = p.Name}).ToList(); 

3
อย่างไรก็ตามสิ่งนี้จะยังคงทำ 'SELECT * FROM [.. ]' ไม่ใช่ 'SELECT name FROM [.. ]'
Timo Hermans

1

เพื่อตอบคำถามอื่นที่ทำเครื่องหมายว่าซ้ำกัน ( ดูที่นี่ ) ฉันพบวิธีแก้ปัญหาที่ง่ายและรวดเร็วตามคำตอบของ Soren:

data.Tasks.AddRange(
    data.Task.AsEnumerable().Select(t => new Task{
        creator_id   = t.ID,
        start_date   = t.Incident.DateOpened,
        end_date     = t.Incident.DateCLosed,
        product_code = t.Incident.ProductCode
        // so on...
    })
);
data.SaveChanges();

หมายเหตุ: วิธีนี้ใช้ได้เฉพาะเมื่อคุณมีคุณสมบัติการนำทาง (รหัสที่ต่างประเทศ) ในคลาสงาน (ที่นี่เรียกว่า 'เหตุการณ์') หากคุณไม่มีคุณสามารถใช้หนึ่งในโซลูชันที่โพสต์อื่น ๆ กับ "AsQueryable ()"


1

คุณสามารถแก้ปัญหานี้ได้โดยใช้ Data Transfer Objects (DTO's)

เหล่านี้เป็นเหมือน viewmodels ที่คุณใส่ในคุณสมบัติที่คุณต้องการและคุณสามารถแมปด้วยตนเองในตัวควบคุมของคุณหรือโดยใช้โซลูชันของบุคคลที่สามเช่น AutoMapper

ด้วย DTO คุณสามารถ:

  • ทำให้ข้อมูลเป็นอนุกรม (Json)
  • กำจัดการอ้างอิงแบบวงกลม
  • ลดประสิทธิภาพของเครือข่ายโดยปล่อยคุณสมบัติที่คุณไม่ต้องการ (viewmodelwise)
  • ใช้วัตถุแบน

ฉันได้เรียนรู้สิ่งนี้ในโรงเรียนในปีนี้และเป็นเครื่องมือที่มีประโยชน์มาก


0

ถ้าคุณใช้ Entity framework ให้ลองลบคุณสมบัติออกจาก DbContext ซึ่งใช้โมเดลที่ซับซ้อนของคุณเป็น Entity ฉันมีปัญหาเดียวกันเมื่อทำการแมปหลาย ๆ โมเดลเข้าใน viewmodel ชื่อ Entity

public DbSet<Entity> Entities { get; set; }

การลบรายการจาก DbContext แก้ไขข้อผิดพลาดของฉัน


0

หากคุณกำลังดำเนินการLinq to Entityคุณจะไม่สามารถใช้ปุ่มClassTypeด้วยnewในการselectปิดคิวรีonly anonymous types are allowed (new without type)

ลองดูตัวอย่างของโครงการของฉัน

//...
var dbQuery = context.Set<Letter>()
                .Include(letter => letter.LetterStatus)
                .Select(l => new {Title =l.Title,ID = l.ID, LastModificationDate = l.LastModificationDate, DateCreated = l.DateCreated,LetterStatus = new {ID = l.LetterStatusID.Value,NameInArabic = l.LetterStatus.NameInArabic,NameInEnglish = l.LetterStatus.NameInEnglish} })
                               ^^ without type__________________________________________________________________________________________________________^^ without type

จากคุณเพิ่มnew keywordในการเลือกปิดแม้ว่าcomplex propertiesคุณจะได้รับข้อผิดพลาดนี้

ดังนั้นคำหลักในคำสั่ง ,,removeClassTypes from newLinq to Entity

เพราะมันจะเปลี่ยนเป็นคำสั่ง sql และดำเนินการบน SqlServer

ดังนั้นเมื่อฉันสามารถใช้new with typesเมื่อselectปิด?

คุณสามารถใช้มันหากคุณกำลังติดต่อกับ LINQ to Object (in memory collection)

//opecations in tempList , LINQ to Entities; so we can not use class types in select only anonymous types are allowed
var tempList = dbQuery.Skip(10).Take(10).ToList();// this is list of <anonymous type> so we have to convert it so list of <letter>

//opecations in list , LINQ to Object; so we can use class types in select
list = tempList.Select(l => new Letter{ Title = l.Title, ID = l.ID, LastModificationDate = l.LastModificationDate, DateCreated = l.DateCreated, LetterStatus = new LetterStatus{ ID = l.LetterStatus.ID, NameInArabic = l.LetterStatus.NameInArabic, NameInEnglish = l.LetterStatus.NameInEnglish } }).ToList();
                                ^^^^^^ with type 

หลังจากที่ฉันดำเนินการToListกับแบบสอบถามมันกลายเป็นin memory collection เพื่อให้เราสามารถใช้new ClassTypesในการเลือก


ตรวจสอบให้แน่ใจว่าคุณสามารถใช้ประเภทที่ไม่ระบุตัวตน แต่คุณไม่สามารถสร้างเอนทิตีภายในการสืบค้น LINQ แม้กระทั่งการตั้งค่าสมาชิกที่ไม่ระบุชื่อเนื่องจาก LINQ-to-Entities ยังคงโยนข้อยกเว้นเดียวกัน
Suncat2000

0

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

วิธีง่ายๆในการทำสิ่งนี้:

IEnumerable<object> list = dataContext.Table.Select(e => new { MyRequiredField = e.MyRequiredField}).AsEnumerable();

0

มันจะไม่ยอมให้คุณแมปกลับสู่ผลิตภัณฑ์เพราะนั่นคือตารางที่คุณทำการสืบค้น คุณต้องการฟังก์ชั่นที่ไม่ระบุชื่อจากนั้นคุณสามารถเพิ่มลงใน ViewModel และเพิ่ม ViewModel แต่ละรายการลงในList<MyViewModel>และส่งคืนสิ่งเหล่านี้ มันเป็นการพูดนอกเรื่องเล็กน้อย แต่ฉันรวม caveats เกี่ยวกับการจัดการวันที่ nullable เพราะสิ่งเหล่านี้เป็นความเจ็บปวดในการจัดการกับด้านหลังในกรณีที่คุณมี นี่คือวิธีที่ฉันจัดการ

หวังว่าคุณจะมีProductViewModel:

public class ProductViewModel
{
    [Key]
    public string ID { get; set; }
    public string Name { get; set; }
}

ฉันมีกรอบการฉีด / เก็บข้อมูลที่ฉันเรียกใช้ฟังก์ชันเพื่อดึงข้อมูลของฉัน ใช้โพสต์ของคุณเป็นตัวอย่างในการเรียกฟังก์ชั่นควบคุมของคุณมันจะมีลักษณะเช่นนี้:

int categoryID = 1;
var prods = repository.GetProducts(categoryID);

ในคลาสที่เก็บ:

public IEnumerable<ProductViewModel> GetProducts(int categoryID)
{
   List<ProductViewModel> lstPVM = new List<ProductViewModel>();

   var anonymousObjResult = from p in db.Products
                            where p.CategoryID == categoryID 
                            select new
                            {
                                CatID = p.CategoryID,
                                Name = p.Name
                            };

        // NOTE: If you have any dates that are nullable and null, you'll need to
        // take care of that:  ClosedDate = (DateTime?)p.ClosedDate ?? DateTime.Now

        // If you want a particular date, you have to define a DateTime variable,
        // assign your value to it, then replace DateTime.Now with that variable. You
        // cannot call a DateTime.Parse there, unfortunately. 
        // Using 
        //    new Date("1","1","1800"); 
        // works, though. (I add a particular date so I can edit it out later.)

        // I do this foreach below so I can return a List<ProductViewModel>. 
        // You could do: return anonymousObjResult.ToList(); here
        // but it's not as clean and is an anonymous type instead of defined
        // by a ViewModel where you can control the individual field types

        foreach (var a in anonymousObjResult)
        {                
            ProductViewModel pvm = new ProductViewModel();
            pvm.ID = a.CatID;  
            pvm.Name = a.Name;
            lstPVM.Add(rvm);
        }

        // Obviously you will just have ONE item there, but I built it 
        // like this so you could bring back the whole table, if you wanted
        // to remove your Where clause, above.

        return lstPVM;
    }

ย้อนกลับไปในคอนโทรลเลอร์คุณทำสิ่งต่อไปนี้

 List<ProductViewModel> lstProd = new List<ProductViewModel>();

 if (prods != null) 
 {
    // For setting the dates back to nulls, I'm looking for this value:
    // DateTime stdDate = DateTime.Parse("01/01/1800");

    foreach (var a in prods)
    {
        ProductViewModel o_prod = new ReportViewModel();
        o_prod.ID = a.ID;
        o_prod.Name = a.Name;
       // o_prod.ClosedDate = a.ClosedDate == stdDate ? null : a.ClosedDate;
        lstProd.Add(o_prod);
    }
}
return View(lstProd);  // use this in your View as:   @model IEnumerable<ProductViewModel>

-1

เพิ่ม AsEnumerable () เท่านั้น:

public IQueryable<Product> GetProducts(int categoryID)
{
    return from p in db.Products.AsEnumerable()
           where p.CategoryID== categoryID
           select new Product { Name = p.Name};
}

8
ไม่เคยทำมัน! สิ่งนี้จะดึงข้อมูลทั้งหมดจากฐานข้อมูลจากนั้นจะทำการเลือก
Gh61

1
นี่คือเหตุผลที่ในบาง บริษัท Linq ถูกห้ามไม่ให้ใช้
hakan

-2

คุณสามารถเพิ่ม AsEnumerable ให้กับคอลเล็กชันของคุณได้ดังต่อไปนี้:

public IQueryable<Product> GetProducts(int categoryID)
{
    return from p in db.Products.AsEnumerable()
           where p.CategoryID== categoryID
           select new Product { Name = p.Name};
}

เหตุใดจึงเป็นคำตอบที่ไม่ถูกต้องแม้ว่าจะทำงาน ... .Anumerable สิ้นสุด linq กับเอนทิตี ส่วนคำสั่ง Where และทุกอย่างอื่นถูกจัดการนอก linq to Entities คือทุกผลิตภัณฑ์จะถูกดึงข้อมูลจากนั้นกรองโดย linq ไปยังวัตถุ นอกเหนือจากนี้มันค่อนข้างตรงกับคำตอบ. ToList ด้านบน stackoverflow.com/questions/5311034/…
KenF

1
ปัญหาเกี่ยวกับสิ่งนี้คือเป็นเพียงการเลือก * จาก ... ดำเนินการไม่ได้เลือกผลิตภัณฑ์ใหม่ {ชื่อ = p.Name} เนื่องจากคุณจะได้รับการอ้างอิงแบบวงกลมด้วย และคุณต้องการเพียงแค่ชื่อ
สเตอร์ลิง Diaz
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.