2016-11-20 12 views
7

tôi đang sử dụng lõi dotnet 1.1 trên linux và tôi đang gặp sự cố khi tôi muốn chia tách identityContext từ dbContext thông thường của mình, bất cứ khi nào tôi chạy dòng sau trong startup.cs của tôi -> configure:Loại thực thể 'IdentityUserLogin <string>' yêu cầu phải có khóa chính để được xác định

//... some other services 
using (var serviceScope = app.ApplicationServices.GetRequiredService<IServiceScopeFactory>().CreateScope()) 
{ 
    serviceScope.ServiceProvider.GetService<ApplicationDbContext>().Database.Migrate(); 
    //running other database.migrations here + seeding data. But it is the line above that causes problems 

Vì vậy dòng này ném ngoại lệ: các loại thực thể 'IdentityUserLogin' đòi hỏi một khóa chính phải được xác định

tôi chỉ đơn giản là không hiểu điều này, tại sao nó là công việc của tôi để cung cấp cho IdentityUserLogin một khóa chính ??, nó là một lớp bên thứ 3 và tôi thậm chí không chạm vào nó. Tôi có các thiết lập sau đây đơn giản:

namespace EsportshubApi.Models 
{ 
    public class ApplicationDbContext : IdentityDbContext<ApplicationUser> 
    { 
     public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options) : base(options) 
     { 
     } 

     public ApplicationDbContext() 
     { 

     } 

     protected override void OnModelCreating(ModelBuilder modelBuilder) 
     { 
      base.OnModelCreating(modelBuilder); 


     } 
    } 
} 

Và applicationUser:

namespace EsportshubApi.Models.Entities 
{ 

    public class ApplicationUser : IdentityUser 
    { 
     public ApplicationUser() { } 

     public static ApplicationUserBuilder Builder() 
     { 
      return new ApplicationUserBuilder(new ApplicationUser()); 
     } 

     public int AccountId { get; set; } 
     public Guid AccountGuid { get; set; } 
     public string Salt { get; set; } 
     public bool Verified { get; set; } 
     public string Checksum { get; set; } 
     public string Password { get; set; } 
     public DateTime Created { get; set; } 
     public DateTime Updated { get; set; } 
    } 

} 

Trong khởi động của tôi tôi đang cấu hình khuôn khổ sắc theo cách sau:

configureServices:

services.AddEntityFrameworkSqlServer().AddMySQL().AddDbContext<ApplicationDbContext>(options => 
        options.UseMySQL(config["ConnectionStrings:DefaultConnection"])); 

Cấu hình:

app.UseIdentity(); 

dự án của tôi là opensourced tại địa chỉ: my github repo

nếu giúp.

Tôi đã thử rất nhiều thứ. Hai hứa hẹn nhất là lấy tất cả các lớp được sử dụng trong chương trình chung này, và chuyển chúng một cách rõ ràng, cố gắng thay đổi tất cả các khóa của chúng thành ints vv. Và nó đã đưa ra cùng một lỗi chính xác chỉ với int thay vì chuỗi. Một cách khác tôi đã cố gắng là làm bên sau OnModelCreating để cung cấp cho IdentityUserLogin một khóa chính bằng cách ví dụ:

modelBuilder.Entity<IdentityUserLogin<int>>() 
      .Property(login => login.UserId) 
      .ForMySQLHasColumnType("PK") 
      .UseSqlServerIdentityColumn() 
      .UseMySQLAutoIncrementColumn("AI"); 

Như bạn có thể thấy, đây là trở lại khi tôi đã UserId như một số nguyên, nhưng tôi thậm chí không chắc chắn nếu UserId phải là primaryKey của nó. Tôi có thể gặp phải các lỗi khác thay vì lỗi này, có nghĩa là

IdentityUserLogin is part of a hierarchy, and it has no discriminator values

Nhưng nếu tôi có giá trị phân biệt thì cuối cùng chỉ quay trở lại lỗi này. Phần kỳ lạ nhất mà tôi nghĩ là tôi có cùng một ví dụ thực hiện giống như ví dụ của UnicornStore github, nó cũng sử dụng một chút khung định danh .... Vì vậy, tôi thực sự cần những người giúp đỡ của bạn. Có thể tạo lại lỗi này bằng cách tải xuống dự án, sao chép default.appsettings.json vào appsettings.json, đặt trong một chuỗi kết nối hợp lệ, dotnet restore, chạy với dotnet run --environment Development.

Tôi thậm chí đã cố gắng thay đổi việc triển khai để sử dụng cơ sở dữ liệu MSSQL thay vì MySQL, nhưng điều đó đã cho cùng một lỗi chính xác.

Trả lời

4

OK. Vì vậy, tôi sẽ cố gắng trả lời câu hỏi của riêng tôi, bởi vì tôi đã vượt qua nó. Nó vẫn có thể theo liên kết github trong OP, và xem dự án tôi đã nhận được lỗi.

Chủ yếu là những gì sai, đó là tôi đã gặp lỗi này khi cố gắng di chuyển ApplicationDbContext : IDentityContext nhưng thực sự là lỗi đã được ném dựa trên dbContext khác của tôi trong ứng dụng, khi tôi cố gắng chạy di chuyển trên đó.Tôi vẫn còn một chút không biết là tại sao DbContext khác lại chọn những thực thể Identity mà tôi không nhắc đến ở bất cứ nơi nào, tôi nghĩ rằng một dbcontext dường như biết một cái gì đó về các thực thể không được đề cập trong phương thức OnModelCreating. Dù sao - khi tôi phát hiện ra rằng nó không phải là IdentityDbContext rằng có điều gì đó sai trái với, tôi chỉ đơn giản là thêm vào sau trong OnModelCreating của bối cảnh đó ném lỗi:

protected override void OnModelCreating(ModelBuilder modelBuilder) 
     { 
      base.OnModelCreating(modelBuilder); 
      modelBuilder.Ignore <IdentityUserLogin<string>>(); 
      modelBuilder.Ignore <IdentityUserRole<string>>(); 
      modelBuilder.Ignore<IdentityUserClaim<string>>(); 
      modelBuilder.Ignore<IdentityUserToken<string>>(); 
      modelBuilder.Ignore<IdentityUser<string>>(); 
      modelBuilder.Ignore<ApplicationUser>(); 

... Vì vậy, tôi vẫn tự hỏi tại sao bối cảnh của tôi là chọn lên trên các thực thể này mà không cần phải làm gì với chúng, và tôi khá lo lắng rằng mỗi khi tôi thêm một bối cảnh, tôi phải loại trừ các mô hình trái với việc đưa chúng vào.

+1

không phải vì bạn đang mở rộng một IdentityDbContext, mà lên hệ thống phân cấp chứa DbSets bây giờ bạn đang bỏ qua? –

+0

Tôi không nhớ chính xác bây giờ, nhưng tôi nghĩ đó là một cái gì đó như thế. Bối cảnh đã ám chỉ họ theo một cách nào đó. – DenLilleMand

1

Tôi đã có một vấn đề tương tự liên quan đến vấn đề ban đầu của bạn, nơi

The entity type 'IdentityUserLogin' requires a primary key to be defined.

Và trong khi tôi nghĩ rằng giải pháp của bạn để bỏ qua các đơn vị dường như làm việc, tôi chỉ muốn cung cấp một giải pháp cho những ai thực sự muốn gán một khóa chính cho mỗi thực thể. Vấn đề là bất cứ khi nào bạn tạo một thực thể, các DbContext sẽ muốn theo dõi khóa chính cho mỗi - do đó, bạn phải gán nó.

Xem ví dụ của tôi bên dưới, trong đó ProjectTarget là các thực thể của tôi và tôi đã chỉ định mỗi thuộc tính mà tôi muốn sử dụng làm khóa chính cho mỗi pháp nhân.

protected override void OnModelCreating(ModelBuilder builder) 
{ 
    builder.Entity<Project>().HasKey(m => m.ProjectPath); 
    builder.Entity<Target>().HasKey(m => m.Guid); 
    base.OnModelCreating(builder); 
} 

Sau khi bạn đã xác định và chỉ định thuộc tính nào sẽ được chỉ định làm khóa chính cho thực thể đó, lỗi sẽ biến mất.

14

phím của bảng Identity được ánh xạ theo phương pháp OnModelCreatingIdentityDbContext và nếu phương pháp này không được gọi, bạn sẽ nhận được lỗi mà bạn nhận được.

Tất cả những gì bạn cần làm là gọi điện.

protected override void OnModelCreating(ModelBuilder modelBuilder) 
{ 
    base.OnModelCreating(modelBuilder); 
} 

Câu trả lời ban đầu (chỉ cần sao chép để tham khảo khác chỉ trong trường hợp) here

+0

Câu trả lời hoàn hảo. Cảm ơn –

+0

Rất vui được giúp bạn! – immirza

Các vấn đề liên quan