นิติบุคคลประเภท <type> ไม่ได้เป็นส่วนหนึ่งของรูปแบบสำหรับบริบทปัจจุบัน


146

ฉันกำลังเข้าสู่ Entity Framework แต่ฉันไม่แน่ใจว่าฉันพลาดจุดสำคัญในวิธีการแบบรหัสแรกหรือไม่

ฉันใช้รูปแบบพื้นที่เก็บข้อมูลทั่วไปตามรหัสจากhttps://genericunitofworkandrepositories.codeplex.com/และได้สร้างเอนทิตีของฉันแล้ว

แต่เมื่อฉันพยายามเข้าถึงหรือแก้ไขเอนทิตีฉันพบสิ่งต่อไปนี้:

System.InvalidOperationException: ประเภทเอนทิตีไม่ได้เป็นส่วนหนึ่งของแบบจำลองสำหรับบริบทปัจจุบัน

มันเกิดขึ้นเมื่อฉันพยายามเข้าถึงจากที่เก็บของฉัน:

public virtual void Insert(TEntity entity)
{
    ((IObjectState)entity).ObjectState = ObjectState.Added;
    _dbSet.Attach(entity); // <-- The error occurs here
    _context.SyncObjectState(entity);
}

ฐานข้อมูล (./SQLEXPRESS) ถูกสร้างอย่างดี แต่เอนทิตี (ตาราง) ไม่ได้ถูกสร้างเมื่อเริ่มต้น

ฉันสงสัยว่าฉันจำเป็นต้องตั้งค่าการแมปเอนทิตีหรือไม่ EF ไม่สามารถทำสิ่งนี้ได้ด้วยตนเอง

เอนทิตีของฉันคือ:

public class Estate : EntityBase
{
    public int EstateId { get; set; }
    public string Name { get; set; }
} 

บริบทของฉันเป็นเช่นนั้น:

public partial class DimensionWebDbContext : DbContextBase // DbContextBase inherits DbContext
{
    public DimensionWebDbContext() :
        base("DimensionWebContext")
    {
        Database.SetInitializer<DimensionWebDbContext>(new CreateDatabaseIfNotExists<DimensionWebDbContext>());
        Configuration.ProxyCreationEnabled = false;
    }

    public new IDbSet<T> Set<T>() where T : class
    {
        return base.Set<T>();
    }

}

มีเหตุผลเฉพาะใด ๆ ที่ทำให้เกิดข้อผิดพลาดนี้หรือไม่? ฉันได้ลองเปิดใช้งานการย้ายข้อมูลและเปิดใช้งานการย้ายข้อมูลอัตโนมัติโดยไม่มีความช่วยเหลือใด ๆ

คำตอบ:


142

ใส่สิ่งนี้ลงในDbContextคลาสที่คุณกำหนดเอง:

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
    modelBuilder.Entity<Estate>().ToTable("Estate");
}

หากตารางของคุณไม่ได้ถูกสร้างเมื่อเริ่มต้นนี่คือเหตุผล คุณต้องบอก DbContext เกี่ยวกับพวกเขาในการแทนที่เมธอด OnModelCreating

คุณสามารถทำการแมปแบบกำหนดเองต่อเอนทิตีที่นี่หรือแยกออกเป็นEntityTypeConfiguration<T>คลาสที่แยกต่างหาก


1
ขอบคุณ Dan - มันช่วยได้ ตอนนี้ตารางจะถูกสร้างขึ้น ไม่มีวิธีอื่นอีกแล้ว EF ไม่สามารถทำได้ด้วยตนเอง ฉันไม่สามารถใส่คำอธิบายประกอบด้วย [ToTable ('Estates')] หรืออะไรแบบนั้น
janhartmann

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

อ่าแน่นอน ขอบคุณที่ทราบเกี่ยวกับวิธีใช้ขาตั้งกล้องฉันได้ทำสิ่งที่คล้ายกันในตอนนี้และดูเหมือนว่าจะทำงานได้ดี (ต้องขอบคุณส่วนขยายการสะท้อนของคุณใน: github.com/danludwig/Layout3/blob/master/UCosmic.Domain/Api/… ) ตอนนี้ฉันแค่ต้องการมันหาชุดประกอบการอ้างอิงแทนที่จะมองว่าชุดประกอบ GetType () "var assembly = Assembly.Load (" Dimension.Web.Domain ");" ไม่สวย ;-)
janhartmann

หรืออาจเพียงแค่ย้าย / Mapping / โฟลเดอร์ใหม่ของฉันไปที่โครงการ Impl ของฉันแทนโดเมนของฉัน
janhartmann

@meep หรือ danludwig คุณช่วยบอกฉันเพิ่มเติมเกี่ยวกับขาตั้งกล้องหรือแชร์ลิงก์ให้ฉันได้ไหม
DkAngelito

73

เห็นได้ชัดว่าข้อผิดพลาดนี้เป็นเรื่องทั่วไปมากอาจมีสาเหตุหลายประการ ในกรณีของฉันมันเป็นดังต่อไปนี้: สตริงการเชื่อมต่อ (ใน Web.config) ที่สร้างขึ้นโดย.edmxไม่ถูกต้อง หลังจากลองทำทุกอย่างเป็นเวลาเกือบหนึ่งวันฉันก็เปลี่ยนสายเชื่อมต่อจากสตริง EF เป็นสตริง ADO.NET นี่เป็นการแก้ไขปัญหาของฉัน

ตัวอย่างเช่นสตริง EF มีลักษณะดังนี้:

<connectionStrings> 
  <add name="BlogContext"  
    connectionString="metadata=res://*/BloggingModel.csdl| 
                               res://*/BloggingModel.ssdl| 
                               res://*/BloggingModel.msl; 
                               provider=System.Data.SqlClient 
                               provider connection string= 
                               &quot;data source=(localdb)\v11.0; 
                               initial catalog=Blogging;
                               integrated security=True; 
                               multipleactiveresultsets=True;&quot;" 
     providerName="System.Data.EntityClient" /> 
</connectionStrings>

และสตริง ADO.NET มีลักษณะดังนี้:

<connectionStrings>
  <add name="BlogContext"  
        providerName="System.Data.SqlClient"  
        connectionString="Server=.\SQLEXPRESS;Database=Blogging;
        Integrated Security=True;"/> 
</connectionStrings>

ที่มา: http://msdn.microsoft.com/nl-nl/data/jj556606.aspx


17
ปัญหาของฉันก็คือในสตริงการเชื่อมต่อ ฉันเปลี่ยนชื่อรุ่นข้อมูลและรันเทมเพลต t4 ใหม่อีกครั้ง แต่ลืมอัปเดตข้อมูลเมตา (.csdl, .ssdl, .msl) ในสตริงการเชื่อมต่อ คำตอบของคุณช่วยให้ฉันตระหนักถึงสิ่งนี้ดังนั้นขอขอบคุณ!
Vyskol

4
หากใช้รูปแบบตัวตนสำหรับการตรวจสอบความถูกต้องคุณต้องมี 2 สตริงการเชื่อมต่อ: อันหนึ่ง "DefaultConnection" ซึ่งคุณสามารถเปลี่ยนชื่อหรือไม่และใส่ใน ApplicationDbContext สาธารณะของคุณสาธารณะ (): ฐาน ("IdentityDbContext", throwIfV1Schema: false) {} เหมือนของคุณ (ฉันมีสตริง EF อยู่ที่นั่น) สตริงการเชื่อมต่อที่สองคือสตริงที่สร้างจากการเพิ่ม EF โดยใช้ตัวช่วยสร้างและจะขอพารามิเตอร์สตริงการเชื่อมต่อ ฉันหวังว่านี่จะช่วยให้ใครบางคน
JustJohn

กันที่นี่ น่าผิดหวังอย่างไม่น่าเชื่อ
Nick Molyneux

1
ผมอัพเกรดจากไปEF 4.x EF 6ฉันต้องสร้างสตริงการเชื่อมต่อใหม่เพื่อเพิ่มตาราง ( DatabaseFirst) ฉันไม่ได้สังเกตเห็นว่าสายเชื่อมต่อของฉันในapp.configและweb.configต่างกัน เมื่อฉันรับช่วงต่อconnectionstringจากapp.configมันก็เริ่มทำงาน
DHFW

16

สำหรับฉันปัญหาคือว่าฉันไม่ได้รวม Entity Class ภายใน db ของฉันตั้งอยู่ภายในบริบทสำหรับกรอบงานเอนทิตี

public DbSet<ModelName> ModelName { get; set; }

12

คุณอาจลองลบตารางออกจากแบบจำลองและเพิ่มอีกครั้ง คุณสามารถทำได้ด้วยการเปิดไฟล์. edmx จาก Solution Explorer

ขั้นตอน:

  1. ดับเบิลคลิกที่ไฟล์. edmx จาก Solution Explorer
  2. คลิกขวาที่หัวตารางที่คุณต้องการลบและเลือก "ลบจากรุ่น"
  3. คลิกขวาอีกครั้งบนพื้นที่ทำงานและเลือก "อัปเดตโมเดลจากฐานข้อมูล .. "
  4. เพิ่มตารางอีกครั้งจากรายการตาราง
  5. ทำความสะอาดและสร้างโซลูชัน

8
ไม่มี. edmx ในรหัส EF ก่อน
Tuukka Haapaniemi

แม้ว่าฉันจะให้ +1 เพราะเขา (หรือคนอื่นที่มีปัญหานี้) อาจต้องการคิดใหม่ในการทำ Code First และทำแบบนี้แทน :)
vapcguy

9

ปัญหาอาจอยู่ในสตริงการเชื่อมต่อ ตรวจสอบให้แน่ใจว่าสตริงการเชื่อมต่อของคุณสำหรับผู้ให้บริการ SqlClient โดยไม่มีข้อมูลเมตาที่เกี่ยวข้องกับ EntityFramework


นี่อาจจะเห็นได้ชัดสำหรับหลาย ๆ คน แต่สิ่งนี้ทำให้ฉันเป็นปัญหา (เกี่ยวกับการผสม db-first กับ code-first) ตอนนี้ฉันสามารถหยุดหมุนวงล้อได้แล้วขอบคุณมาก!
Bonez024

3

ฉันเห็นข้อผิดพลาดนี้เมื่อตารางที่มีอยู่ในฐานข้อมูลไม่ได้แมปกับรหัสรุ่นแรกอย่างเหมาะสม โดยเฉพาะฉันมีถ่าน (1) ในตารางฐานข้อมูลและถ่านใน C # การเปลี่ยนรูปแบบเป็นสตริงสามารถแก้ไขปัญหาได้


3

ปัญหาของฉันได้รับการแก้ไขโดยการอัปเดตส่วนเมทาดาทาของสตริงการเชื่อมต่อ เห็นได้ชัดว่ามีการชี้ไปที่การอ้างอิง. csll / .ssdl / .msl ที่ไม่ถูกต้อง


เรื่องนี้เกิดขึ้นกับฉันด้วย ฉันคัดลอกสายเชื่อมต่อ EF จากที่อื่นและไม่ได้อัปเดตชื่อรุ่นในข้อมูลเมตา
devC

2

อีกสิ่งหนึ่งในการตรวจสอบกับสตริงการเชื่อมต่อของคุณ - ชื่อรุ่น ฉันใช้สองโมเดลเอนทิตี DB ก่อน ในการกำหนดค่าฉันคัดลอกการเชื่อมต่อเอนทิตี้สำหรับหนึ่งเปลี่ยนชื่อและเปลี่ยนส่วนสตริงการเชื่อมต่อ สิ่งที่ฉันไม่ได้เปลี่ยนคือชื่อรุ่นดังนั้นในขณะที่โมเดลเอนทิตีสร้างขึ้นอย่างถูกต้องเมื่อบริบทเริ่มต้น EF กำลังมองหาโมเดลที่ผิดสำหรับเอนทิตี

ดูชัดเจนเขียนลง แต่มีสี่ชั่วโมงฉันจะไม่กลับ


2

สำหรับฉันปัญหาคือว่าฉันใช้connection stringสร้างโดยADO.NetModel (.edmx) การเปลี่ยนสายเชื่อมต่อสามารถแก้ไขปัญหาของฉันได้


1

สิ่งนี้สามารถเกิดขึ้นได้หากคุณใช้แคชรุ่นที่เก็บไว้ซึ่งล้าสมัยด้วยเหตุผลใดเหตุผลหนึ่ง หากบริบทของคุณถูกแคชไปยังไฟล์ EDMX บนระบบไฟล์ (ผ่าน DbConfiguration.SetModelStore) ดังนั้น OnModelCreating จะไม่ถูกเรียกใช้เนื่องจากเวอร์ชันแคชจะถูกใช้ ดังนั้นหากเอนทิตีหายไปจากที่เก็บแคชของคุณคุณจะได้รับข้อผิดพลาดด้านบนแม้ว่าสตริงการเชื่อมต่อนั้นถูกต้องตารางอยู่ในฐานข้อมูลและเอนทิตีถูกตั้งค่าอย่างถูกต้องใน DbContext ของคุณ


1

ข้อความค่อนข้างชัดเจน แต่ฉันไม่เข้าใจในตอนแรก ...

ฉันทำงานกับบริบท Entity Framework DB สองรายการsysContextและshardContextใช้วิธีเดียวกัน

เอนทิตีที่ฉันแก้ไข \ update มาจากบริบทหนึ่ง แต่จากนั้นฉันพยายามบันทึกลงในบริบทอื่นเช่นนี้:

invite.uid = user.uid;

sysContext.Entry(invite).State = EntityState.Modified;

sysContext.SaveChanges(); // Got the exception here

แต่รุ่นที่ถูกต้องควรเป็น:

invite.uid = user.uid;

shardContext.Entry(invite).State = EntityState.Modified;

shardContext.SaveChanges();

หลังจากส่งเอนทิตีไปยังบริบทที่ถูกต้องข้อผิดพลาดนี้ก็หายไป


0

ฟังดูชัดเจน แต่ให้แน่ใจว่าคุณไม่สนใจประเภทดังกล่าวอย่างชัดเจน:

modelBuilder.Ignore<MyType>();


0

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



0

Visual Studio 2019ดูเหมือนจะเป็นสาเหตุให้ฉัน ฉันแก้ไขโดยสร้างโมเดล edmx อีกครั้งในปี 2560


0

ฉันได้รับปัญหาเดียวกันใน Entity Framewrok และฉันแก้ไขได้โดยทำตามขั้นตอน:

1- เปิด Model.edmx ของคุณ 2 เปลี่ยนตำแหน่งของตาราง (สำหรับทำการเปลี่ยนแปลงในไฟล์ cs) 3 บันทึก

ฉันหวังว่าจะช่วยคุณ


0

ลบไฟล์. edmx และเพิ่มอีกครั้ง โดยเฉพาะอย่างยิ่งถ้าคุณได้อัพเกรด Entity Framework


0

ฉันกำลังเผชิญปัญหาเดียวกันกับ EntityFrameworkCore พยายามอัปเดตช่วงของค่า

วิธีนี้ไม่ได้ผล

  _dbSet.AttachRange(entity);
  _context.Entry(entity).State = EntityState.Modified;
   await _context.SaveChangesAsync().ConfigureAwait(false);

หลังจากเพิ่มเมธอด UpdateRange แล้วลบสิ่งที่แนบและรายการทุกอย่างทำงาน

  _dbSet.UpdateRange(entity);
  await _context.SaveChangesAsync().ConfigureAwait(false);

0

สำหรับฉันมันเกิดขึ้นเพราะฉันเปลี่ยนชื่อคลาสเอนทิตีเมื่อฉันย้อนกลับไปมันก็โอเค


0

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


0

ฉันมีสิ่งนี้

using (var context = new ATImporterContext(DBConnection))
{
    if (GetID(entity).Equals(0))
    {
        context.Set<T>().Add(entity);
    }
    else
    {
        int val = GetID(entity);
        var entry = GetEntryAsync(context, GetID(entity)).ConfigureAwait(false);
        context.Entry(entry).CurrentValues.SetValues(entity);

    }
    
    await context.SaveChangesAsync().ConfigureAwait(false);
}

นี่เป็นวิธี async แต่ฉันลืมที่จะรอก่อน GetEntryAsync และดังนั้นฉันจึงได้รับข้อผิดพลาดเดียวกันนี้ ...

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