Loại thực thể <type> không phải là một phần của mô hình cho bối cảnh hiện tại


146

Tôi đang tham gia vào Entity Framework, nhưng tôi không chắc liệu tôi có thiếu một điểm quan trọng trong cách tiếp cận mã đầu tiên hay không.

Tôi đang sử dụng một mẫu kho lưu trữ chung dựa trên mã từ https://genericunitofworkandrepos khu.codeplex.com/ và đã tạo ra các thực thể của tôi.

Nhưng khi tôi cố gắng truy cập hoặc sửa đổi thực thể tôi gặp phải như sau:

System.InvalidOperationException: Kiểu thực thể động sản không phải là một phần của mô hình cho bối cảnh hiện tại.

Nó xảy ra khi tôi đang cố truy cập nó từ kho lưu trữ của mình:

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

Cơ sở dữ liệu (./SQLEXPRESS) được tạo tốt, nhưng các thực thể (bảng) không được tạo khi khởi động.

Tôi tự hỏi nếu tôi cần thiết lập rõ ràng ánh xạ của các thực thể? Là EF không thể tự điều này?

Thực thể của tôi là:

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

Bối cảnh của tôi là như vậy:

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

}

Có bất kỳ lý do cụ thể tại sao lỗi này xảy ra? Tôi đã thử kích hoạt di chuyển và cho phép di chuyển tự động mà không cần bất kỳ trợ giúp.

Câu trả lời:


141

Đặt cái này trong DbContextlớp tùy chỉnh của bạn :

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

Nếu các bảng của bạn không được tạo khi khởi động, đây là lý do. Bạn cần nói với DbContext về chúng trong ghi đè phương thức OnModelCreating.

Bạn có thể thực hiện ánh xạ cho mỗi thực thể tùy chỉnh tại đây hoặc tách chúng thành EntityTypeConfiguration<T>các lớp riêng biệt .


1
Cảm ơn, Dan - cái này sửa nó. Bây giờ các bảng được tạo ra. Không còn cách nào khác, EF không thể tự mình làm điều này? Tôi không thể chú thích thực thể bằng [ToTable ('Estates')] hoặc đại loại như thế?
janhartmann

3
Tôi nghĩ rằng nó có thể hoạt động mà không ghi đè OnModelCreatingnếu các thực thể của bạn nằm trong cùng một tổ hợp với bạn DbContext. Tôi chưa bao giờ sử dụng chú thích dữ liệu cho các thực thể, vì vậy tôi không thể nói chắc chắn. Bạn luôn có thể quét các cụm trong OnModelCreatingđể tìm các thực thể trong các cụm khác và đăng ký chúng tự động (đó là những gì Chân máy làm).
danludwig

À, tất nhiên rồi. Cảm ơn bạn đã lưu ý về cách làm Chân máy, tôi đã làm một cái gì đó tương tự và dường như nó hoạt động tốt. (cũng nhờ vào phần mở rộng suy nghĩ của bạn về: github.com/danludwig/Layout3/blob/master/UCosmic.Domain/Api/... ). Bây giờ tôi chỉ cần nó tìm các tập hợp tham chiếu thay vì tìm mặc dù tập hợp GetType (). "var assembly = hội đồng. Tải (" Dimension.Web.Domain ");" không đẹp ;-)
janhartmann 19/12/13

Hoặc có thể chỉ cần di chuyển thư mục / Ánh xạ / mới của tôi vào dự án Impl của tôi thay vì Miền của tôi.
janhartmann

@meep hoặc danludwig. Bạn có thể vui lòng cho tôi biết thêm về giá ba chân hoặc chia sẻ cho tôi một liên kết.
DkAngelito

73

Rõ ràng, lỗi này rất chung chung, nó có thể có một số lý do. Trong trường hợp của tôi, nó là như sau: Chuỗi kết nối (trong Web.config) được tạo bởi .edmxkhông hợp lệ. Sau gần một ngày thử mọi thứ, tôi đã thay đổi chuỗi kết nối từ chuỗi EF thành chuỗi ADO.NET. Điều này đã giải quyết vấn đề của tôi.

Ví dụ, chuỗi EF trông giống như thế này:

<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>

Và chuỗi ADO.NET trông như thế này:

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

Nguồn: http://msdn.microsoft.com/nl-nl/data/jj556606.aspx


17
Vấn đề của tôi cũng nằm trong chuỗi kết nối. Tôi đã đổi tên mô hình dữ liệu của mình và chạy lại các mẫu t4 của mình, nhưng quên cập nhật siêu dữ liệu (các tệp .csdl, .ssdl, .msl) trong chuỗi kết nối. Câu trả lời của bạn đã giúp tôi nhận ra điều này, vì vậy cảm ơn bạn!
Vyskol

4
Nếu sử dụng mô hình Nhận dạng để xác thực, bạn cần 2 chuỗi kết nối: một, "DefaultConnection" mà bạn có thể đổi tên hoặc không và đặt vào ApplicationDbContext (): base ("IdentityDbContext", throw IfV1Schema: false) {} Đó là lỗi gây ra giống như của bạn (tôi đã có chuỗi EF ở đó). Chuỗi kết nối thứ hai là chuỗi được tạo từ việc thêm EF bằng trình hướng dẫn và nó yêu cầu các tham số chuỗi Kết nối. Tôi hi vọng điêu nay se giup được ai đo.
JustJohn

tương tự ở đây cực kỳ bực bội
Nick Molyneux

1
Tôi nâng cấp từ EF 4.xđến EF 6. Tôi đã phải tạo lại chuỗi kết nối để thêm bảng ( DatabaseFirst). Tôi đã không nhận thấy rằng kết nối của tôi trong app.configweb.configkhác nhau. Khi tôi tiếp quản connectionstringtừ app.config, nó bắt đầu hoạt động.
DHFW

16

Đối với tôi, vấn đề là tôi đã không bao gồm Lớp thực thể trong db được đặt trong bối cảnh cho khung thực thể.

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

12

Bạn có thể thử xóa bảng khỏi mô hình và thêm lại. Bạn có thể thực hiện điều này một cách trực quan bằng cách mở tệp .edmx từ Solution Explorer.

Các bước:

  1. Nhấp đúp vào tệp .edmx từ Solution Explorer
  2. Nhấp chuột phải vào đầu bảng bạn muốn xóa và chọn "Xóa khỏi Mô hình"
  3. Bây giờ một lần nữa nhấp chuột phải vào khu vực làm việc và chọn "Cập nhật mô hình từ cơ sở dữ liệu .."
  4. Thêm bảng một lần nữa từ danh sách bảng
  5. Làm sạch và xây dựng giải pháp

8
Không có .edmx trong Mã EF đầu tiên.
Tuukka Haapaniemi

Tuy nhiên, tôi đã cho +1 vì anh ấy (hoặc người khác có vấn đề này) có thể muốn nghĩ lại việc thực hiện Code First và thực hiện theo cách này, thay vào đó :)
vapcguy

9

Vấn đề có thể nằm trong chuỗi kết nối. Đảm bảo chuỗi kết nối của bạn dành cho nhà cung cấp SqlClient, không có nội dung siêu dữ liệu liên quan đến EntityFramework.


Điều này có thể rõ ràng đối với nhiều người, nhưng đây là vấn đề của tôi (liên quan đến việc trộn db-trước với mã đầu tiên). Bây giờ tôi có thể ngừng quay bánh xe của tôi, cảm ơn bạn rất nhiều!
Bonez024

3

Tôi đã thấy lỗi này khi một bảng hiện có trong cơ sở dữ liệu không ánh xạ thích hợp vào mô hình mã đầu tiên. Cụ thể tôi đã có một char (1) trong bảng cơ sở dữ liệu và một char trong C #. Thay đổi mô hình thành một chuỗi giải quyết vấn đề.


3

Vấn đề của tôi đã được giải quyết bằng cách cập nhật phần siêu dữ liệu của chuỗi kết nối. Rõ ràng nó đã chỉ vào tham chiếu .csdl / .ssdl / .msl sai.


Điều này xảy ra với tôi quá. Tôi đã sao chép chuỗi kết nối EF từ một nơi khác và chưa cập nhật tên mô hình trong dữ liệu meta.
devC

2

Một điều khác để kiểm tra với chuỗi kết nối của bạn - tên mô hình. Tôi đã sử dụng hai mô hình thực thể, DB đầu tiên. Trong cấu hình, tôi đã sao chép kết nối thực thể cho một, đổi tên nó và thay đổi phần chuỗi kết nối. Cái tôi không thay đổi là tên mô hình, vì vậy trong khi mô hình thực thể được tạo chính xác, khi bối cảnh được khởi tạo, EF đã tìm kiếm mô hình sai cho các thực thể.

Có vẻ rõ ràng được viết ra, nhưng có bốn giờ tôi sẽ không quay lại.


2

Đối với tôi, vấn đề là tôi đã sử dụng Model connection stringđược tạo ADO.Net(.edmx). Thay đổi chuỗi kết nối đã giải quyết vấn đề của tôi.


1

Điều này cũng có thể xảy ra nếu bạn đang sử dụng bộ đệm mô hình liên tục đã hết hạn vì lý do này hay lý do khác. Nếu ngữ cảnh của bạn đã được lưu vào bộ đệm EDMX trên hệ thống tệp (thông qua DbConfiguration.SetModelStore) thì OnModelCreating sẽ không bao giờ được gọi là phiên bản được lưu trong bộ nhớ cache. Kết quả là nếu một thực thể bị thiếu trong cửa hàng được lưu trong bộ nhớ cache của bạn thì bạn sẽ gặp lỗi ở trên mặc dù chuỗi kết nối là chính xác, bảng tồn tại trong cơ sở dữ liệu và thực thể được thiết lập chính xác trong DbContext của bạn.


1

Thông điệp khá rõ ràng nhưng lúc đầu tôi không nhận được ...

Tôi đang làm việc với hai bối cảnh DB thực thể sysContextshardContext trong cùng một phương thức.

Thực thể tôi đã sửa đổi \ cập nhật là từ một bối cảnh nhưng sau đó tôi đã cố lưu nó vào bối cảnh khác như thế này:

invite.uid = user.uid;

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

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

nhưng phiên bản chính xác phải là cái này:

invite.uid = user.uid;

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

shardContext.SaveChanges();

Sau khi chuyển thực thể đến đúng ngữ cảnh, lỗi này đã biến mất.


0

Nghe có vẻ rõ ràng, nhưng hãy chắc chắn rằng bạn không bỏ qua loại này:

modelBuilder.Ignore<MyType>();


0

bản đồ của thực thể (thậm chí là một sản phẩm trống) được thêm vào cấu hình sẽ dẫn đến việc loại thực thể là một phần của bối cảnh. Chúng tôi có một thực thể không có mối quan hệ với các thực thể khác được cố định với một bản đồ trống.


0

nếu bạn đang thử DB trước thì hãy chắc chắn rằng bảng của bạn có khóa chính


0

Visual Studio 2019 dường như gây ra điều này cho tôi. Tôi đã sửa nó bằng cách tạo lại mô hình edmx vào năm 2017.


0

Tôi gặp vấn đề tương tự trong Entity Framewrok và tôi đã giải quyết nó theo các bước:

1-Mở Model.edmx của bạn 2-thay đổi vị trí bảng (để thay đổi trong tệp cs) 3-lưu nó

Tôi hy vọng giúp bạn


0

Xóa tệp .edmx và thêm lại. Đặc biệt, nếu bạn đã nâng cấp Entity Framework.


0

Tôi đã phải đối mặt với cùng một vấn đề với EntityFrameworkCore đang cố gắng cập nhật một loạt các giá trị.

Cách tiếp cận này không hiệu quả

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

Sau khi thêm phương thức UpdateRange và xóa tệp đính kèm và nhập, mọi thứ đều hoạt động

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

0

Đối với tôi nó được gây ra bởi vì tôi đã đổi tên lớp thực thể. Khi tôi quay lại, nó đã ổn.


0

Có thể là ngu ngốc, nhưng nếu bạn chỉ gặp lỗi này trên một số Bảng, đừng quên làm sạch dự án của bạn và xây dựng lại (có thể tiết kiệm rất nhiều thời gian)


0

Tôi đã có cái này

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

Đây là một phương thức không đồng bộ, nhưng tôi đã quên chờ đợi trước GetEntryAsync, và vì vậy tôi đã gặp lỗi tương tự ...

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.