Saya bekerja dengan Entity Framework Code First dan MVC 5. Ketika saya membuat aplikasi saya dengan Otentikasi Akun Pengguna Individual, saya diberi pengontrol Akun dan bersama dengan itu semua kelas dan kode yang diperlukan yang diperlukan untuk membuat otentikasi Akun Pengguna Indiv berfungsi .
Di antara kode yang sudah ada adalah ini:
public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
{
public ApplicationDbContext() : base("DXContext", throwIfV1Schema: false)
{
}
public static ApplicationDbContext Create()
{
return new ApplicationDbContext();
}
}
Tapi kemudian saya melanjutkan dan membuat konteks saya sendiri menggunakan kode terlebih dahulu, jadi saya sekarang memiliki yang berikut ini juga:
public class DXContext : DbContext
{
public DXContext() : base("DXContext")
{
}
public DbSet<ApplicationUser> Users { get; set; }
public DbSet<IdentityRole> Roles { get; set; }
public DbSet<Artist> Artists { get; set; }
public DbSet<Paintings> Paintings { get; set; }
}
Akhirnya saya memiliki metode seed berikut untuk menambahkan beberapa data untuk saya kerjakan sambil mengembangkan:
protected override void Seed(DXContext context)
{
try
{
if (!context.Roles.Any(r => r.Name == "Admin"))
{
var store = new RoleStore<IdentityRole>(context);
var manager = new RoleManager<IdentityRole>(store);
var role = new IdentityRole { Name = "Admin" };
manager.Create(role);
}
context.SaveChanges();
if (!context.Users.Any(u => u.UserName == "James"))
{
var store = new UserStore<ApplicationUser>(context);
var manager = new UserManager<ApplicationUser>(store);
var user = new ApplicationUser { UserName = "James" };
manager.Create(user, "ChangeAsap1@");
manager.AddToRole(user.Id, "Admin");
}
context.SaveChanges();
string userId = "";
userId = context.Users.FirstOrDefault().Id;
var artists = new List<Artist>
{
new Artist { FName = "Salvador", LName = "Dali", ImgURL = "http://i62.tinypic.com/ss8txxn.jpg", UrlFriendly = "salvador-dali", Verified = true, ApplicationUserId = userId },
};
artists.ForEach(a => context.Artists.Add(a));
context.SaveChanges();
var paintings = new List<Painting>
{
new Painting { Title = "The Persistence of Memory", ImgUrl = "http://i62.tinypic.com/xx8tssn.jpg", ArtistId = 1, Verified = true, ApplicationUserId = userId }
};
paintings.ForEach(p => context.Paintings.Add(p));
context.SaveChanges();
}
catch (DbEntityValidationException ex)
{
foreach (var validationErrors in ex.EntityValidationErrors)
{
foreach (var validationError in validationErrors.ValidationErrors)
{
Trace.TraceInformation("Property: {0} Error: {1}", validationError.PropertyName, validationError.ErrorMessage);
}
}
}
}
Solusi saya dibangun dengan baik, tetapi ketika saya mencoba dan mengakses pengontrol yang memerlukan akses ke database saya mendapatkan kesalahan berikut:
DX.DOMAIN.Context.IdentityUserLogin:: EntityType 'IdentityUserLogin' tidak memiliki kunci yang ditentukan. Tentukan kunci untuk EntityType ini.
DX.DOMAIN.Context.IdentityUserRole:: EntityType 'IdentityUserRole' tidak memiliki kunci yang ditentukan. Tentukan kunci untuk EntityType ini.
Apa yang saya lakukan salah? Apakah karena saya memiliki dua konteks?
MEMPERBARUI
Setelah membaca jawaban Augusto, saya memilih Opsi 3 . Inilah tampilan kelas DXContext saya sekarang:
public class DXContext : DbContext
{
public DXContext() : base("DXContext")
{
// remove default initializer
Database.SetInitializer<DXContext>(null);
Configuration.LazyLoadingEnabled = false;
Configuration.ProxyCreationEnabled = false;
}
public DbSet<User> Users { get; set; }
public DbSet<Role> Roles { get; set; }
public DbSet<Artist> Artists { get; set; }
public DbSet<Painting> Paintings { get; set; }
public static DXContext Create()
{
return new DXContext();
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Entity<User>().ToTable("Users");
modelBuilder.Entity<Role>().ToTable("Roles");
}
public DbQuery<T> Query<T>() where T : class
{
return Set<T>().AsNoTracking();
}
}
Saya juga menambahkan sebuah User.cs
dan Role.cs
kelas, tampilannya seperti ini:
public class User
{
public int Id { get; set; }
public string FName { get; set; }
public string LName { get; set; }
}
public class Role
{
public int Id { set; get; }
public string Name { set; get; }
}
Saya tidak yakin apakah saya memerlukan properti kata sandi pada pengguna, karena ApplicationUser default memiliki itu dan banyak bidang lainnya!
Bagaimanapun, perubahan di atas berjalan dengan baik, tetapi sekali lagi saya mendapatkan kesalahan ini ketika aplikasi dijalankan:
Nama kolom UserId tidak valid
UserId
adalah properti integer di my Artist.cs
AddOrUpdate(new EntityObject { shoes = green})
juga dikenal sebagai "upsert". menentang hanya menambahkan ke konteks, jika tidak Anda hanya akan membuat info konteks entitas duplikat / berlebihan.Dalam kasus saya, saya telah mewarisi dari IdentityDbContext dengan benar (dengan jenis dan kunci kustom saya sendiri yang ditentukan) tetapi secara tidak sengaja telah menghapus panggilan ke OnModelCreating kelas dasar:
Yang kemudian memperbaiki indeks saya yang hilang dari kelas identitas dan saya kemudian dapat menghasilkan migrasi dan mengaktifkan migrasi dengan tepat.
sumber
Bagi mereka yang menggunakan ASP.NET Identity 2.1 dan telah mengubah kunci utama dari default
string
ke salah satuint
atauGuid
, jika Anda masih mendapatkanAnda mungkin lupa menentukan jenis kunci baru pada
IdentityDbContext
:Jika Anda baru saja
atau bahkan
Anda akan mendapatkan kesalahan 'tidak ada kunci yang ditentukan' saat Anda mencoba menambahkan migrasi atau memperbarui database.
sumber
Dengan Mengubah DbContext Seperti Di Bawah Ini;
Hanya menambahkan
OnModelCreating
panggilan metode ke base.OnModelCreating (modelBuilder); dan itu menjadi baik. Saya menggunakan EF6.Terima Kasih Khusus Untuk #Senator
sumber
sumber
Masalah saya serupa - Saya memiliki tabel baru yang saya buat ahd itu untuk mengikat pengguna identitas. Setelah membaca jawaban di atas, menyadari itu ada hubungannya dengan IsdentityUser dan properti yang diwarisi. Saya sudah menyiapkan Identitas sebagai Konteksnya sendiri, jadi untuk menghindari secara inheren mengikat keduanya, daripada menggunakan tabel pengguna terkait sebagai properti EF yang sebenarnya, saya menyiapkan properti yang tidak dipetakan dengan kueri untuk mendapatkan entitas terkait. (DataManager disiapkan untuk mengambil konteks saat ini di mana OtherEntity ada.)
sumber