FK is linked to tbWarehouseUser 1 recording.
There are both lowercase and uppercase values in the tbWarehouseUser table.
How can I solve this problem ?
The classes are as follows;
private void Form1_Load(object sender, EventArgs e)
{
var model = new Model1();
var tbWarehouse = model.tbWarehouse.Where(c=> c.sWarehouse == "A1").FirstOrDefault();
var tbWarehouseUserList = tbWarehouse.tbWarehouseUser.ToList();
}
tbWarehouseUserList.Count record count 1.
1 record is coming. This problem causes sourced?
Recording picture
public partial class tbWarehouse
{
tbWarehouse()
{
tbWarehouseUser = new HashSet<tbWarehouseUser>();
}
[Key]
[StringLength(4)]
public string sWarehouse { get; set; }
public string WarehouseDescription { get; set; }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<tbWarehouseUser> tbWarehouseUser { get; set; }
}
public partial class tbWarehouseUser
{
[Key]
[Column(Order = 0)]
[StringLength(4)]
public string sUserName { get; set; }
[Key]
[Column(Order = 1)]
[StringLength(4)]
public string sWarehouseName { get; set; }
public string sUserPass { get; set; }
public virtual tbWarehouse tbWarehouse { get; set; }
}
public partial class Model1 : DbContext
{
public Model1()
: base("name=Model1")
{
}
protected void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<tbWarehouse>()
.Property(e => e.sWarehouse)
.IsFixedLength()
.IsUnicode(false);
modelBuilder.Entity<tbWarehouse>()
.Property(e => e.WarehouseDescription)
.IsUnicode(false);
modelBuilder.Entity<tbWarehouse>()
.HasMany(e => e.tbWarehouseUser)
.WithRequired(e => e.tbWarehouse)
.HasForeignKey(e => e.sWarehouseName)
.WillCascadeOnDelete(false);
modelBuilder.Entity<tbWarehouseUser>()
.Property(e => e.sUserName)
.IsFixedLength()
.IsUnicode(false);
modelBuilder.Entity<tbWarehouseUser>()
.Property(e => e.sWarehouseName)
.IsFixedLength()
.IsUnicode(false);
modelBuilder.Entity<tbWarehouseUser>()
.Property(e => e.sUserPass)
.IsFixedLength()
.IsUnicode(false);
}
}
Related
I want to change a foreign key on my table from not nullable to nullable
Class name : DestinatairePartageDocument
public class DestinatairePartageDocument
{
[Key]
public int DestinatairePartageDocumentId { get; set; }
//[ForeignKey("Document")]
//public int DocumentId { get; set; }
[ForeignKey("Document")]
public int? DocumentId { get; set; }
public Document Document { get; set; }
//[ForeignKey("Examen")]
[NotMapped]
public int? ExamenId { get; set; }
//public Examen Examen { get; set; }
[ForeignKey("DestinatairePartage")]
public int DestinatairePartageId { get; set; }
public DestinatairePartage DestinatairePartage { get; set; }
public string CodeAccesDocument { get; set; }
public DateTime DateFinValiditeCodeAccesDocument { get; set; }
public string TypePartage { get; set; } /* PartageClassique, PartageCodeGenere */
public string StatutDocument { get; set; }
public bool PartageActive { get; set; }
public DateTime DateCreation { get; set; }
public DateTime DateDerniereModification { get; set; }
}
Old property setup :
[ForeignKey("Document")]
public int DocumentId { get; set; }
public Document Document { get; set; }
New property setup :
[ForeignKey("Document")]
public int? DocumentId { get; set; }
public Document Document { get; set; }
Upon doing this update, I then update my migration schema :
dotnet ef Migrations add UpdateDocumentNullable
And then I apply the modification to the database :
dotnet ef database update
But I then have the following error "FOREIGN KEY constraint failed" :
Here is the migration file generated :
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropForeignKey(
name: "FK_DestinatairesPartageDocuments_Documents_DocumentId",
table: "DestinatairesPartageDocuments");
migrationBuilder.AddColumn<string>(
name: "StatutPartageExamen",
table: "Examens",
type: "TEXT",
nullable: true);
migrationBuilder.AlterColumn<int>(
name: "DocumentId",
table: "DestinatairesPartageDocuments",
type: "INTEGER",
nullable: true,
oldClrType: typeof(int),
oldType: "INTEGER");
migrationBuilder.AddColumn<int>(
name: "ExamenId",
table: "DestinatairesPartageDocuments",
type: "INTEGER",
nullable: true);
migrationBuilder.AddForeignKey(
name: "FK_DestinatairesPartageDocuments_Documents_DocumentId",
table: "DestinatairesPartageDocuments",
column: "DocumentId",
principalTable: "Documents",
principalColumn: "DocumentId",
onDelete: ReferentialAction.Restrict);
}
Below are the queries created from the migration :
My DbContext class :
public class ApplicationDbContext: IdentityDbContext<ApplicationUser>, IDataProtectionKeyContext
{
private readonly ILoggerFactory _loggerFactory;
public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options, ILoggerFactory loggerFactory) : base(options)
{
_loggerFactory = loggerFactory;
}
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder.UseLoggerFactory(_loggerFactory);
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
//modelBuilder.Entity<DestinatairePartageDocument>()
// .Property(dpd => dpd.DocumentId)
// .HasDefaultValueSql("NULL");
//modelBuilder.Entity<DestinatairePartageDocument>()
// .HasOne(dpd => dpd.Document)
// .WithMany()
// .OnDelete(DeleteBehavior.Cascade);
//modelBuilder.Entity<DestinatairePartageDocument>()
// .HasOne("PortailWorker.Models.Document", "Document")
// .WithMany()
// .HasForeignKey("DocumentId");
modelBuilder.Entity<DestinatairePartageDocument>()
.Property(ap => ap.DateCreation)
.HasDefaultValueSql("CURRENT_TIMESTAMP");
modelBuilder.Entity<DestinatairePartageDocument>()
.Property(ap => ap.DateDerniereModification)
.HasDefaultValueSql("CURRENT_TIMESTAMP");
modelBuilder.Entity<Revendeur>()
.HasMany(r => r.ListeClients)
.WithOne(c => c.Revendeur);
modelBuilder.Entity<ClientWPFFetcher>()
.HasKey(cwf => new { cwf.ClientId, cwf.WPFFetcherId });
modelBuilder.Entity<ClientWPFFetcher>()
.Property(cwf => cwf.RelationActivated)
.HasDefaultValue(true);
modelBuilder.Entity<ClientWPFFetcher>()
.HasOne(cwf => cwf.Client)
.WithMany(c => c.ClientWPFFetchers)
.HasForeignKey(cwl => cwl.ClientId);
modelBuilder.Entity<ClientWPFFetcher>()
.HasOne(cwf => cwf.WPFFetcher)
.WithMany(c => c.ClientWPFFetchers)
.HasForeignKey(cwl => cwl.WPFFetcherId);
modelBuilder.Entity<ClientWorkerLocal>()
.HasKey(cwl => new { cwl.ClientId, cwl.WorkerLocalId });
modelBuilder.Entity<ClientWorkerLocal>()
.Property(cwl => cwl.RelationActivated)
.HasDefaultValue(true);
modelBuilder.Entity<ClientWorkerLocal>()
.HasOne(cwl => cwl.Client)
.WithMany(c => c.ClientWorkersLocal)
.HasForeignKey(cwl => cwl.ClientId);
modelBuilder.Entity<ClientWorkerLocal>()
.HasOne(cwl => cwl.WorkerLocal)
.WithMany(c => c.ClientWorkersLocal)
.HasForeignKey(cwl => cwl.WorkerLocalId);
modelBuilder.Entity<Client>()
.Property(ap => ap.ActivationStatus)
.HasDefaultValue(1);
modelBuilder.Entity<Revendeur>()
.Property(ap => ap.ActivationStatus)
.HasDefaultValue(1);
modelBuilder.Entity<WorkerLocal>()
.Property(ap => ap.ActivationStatus)
.HasDefaultValue(1);
modelBuilder.Entity<ConfigurationWorker>()
.Property(cw => cw.Jpeg2000LossyRate)
.HasDefaultValue(40);
modelBuilder.Entity<ConfigurationWorker>()
.Property(cw => cw.ActiverBackgroundServiceWorker)
.HasDefaultValue(true);
modelBuilder.Entity<WorkerLocal>()
.Property(ap => ap.EnLigne)
.HasDefaultValue(false);
modelBuilder.Entity<WorkerLocal>()
.Property(ap => ap.UtilisationCPUPourcentage)
.HasDefaultValue(0.00);
modelBuilder.Entity<WorkerLocal>()
.Property(ap => ap.UtilisationRAMPourcentage)
.HasDefaultValue(0.00);
modelBuilder.Entity<WorkerLocal>()
.Property(ap => ap.UtilisationStockagePourcentage)
.HasDefaultValue(0.00);
modelBuilder.Entity<MappingHL7>()
.Property(m => m.SegmentId)
.HasDefaultValue(1);
modelBuilder.Entity<MappingHL7>()
.Property(m => m.ChampsHL7RepetitionId)
.HasDefaultValue(1);
modelBuilder.Entity<MappingHL7>()
.Property(m => m.SousComposantHL7)
.HasDefaultValue(1);
modelBuilder.Entity<MappingHL7>()
.Property(m => m.TypeMessage)
.HasDefaultValue("Tous");
}
public DbSet<RegleTraitementImage> ReglesTraitementImage { get; set; }
public DbSet<CritereSelectionRegle> CriteresSelectionRegle { get; set; }
public DbSet<AETDemandeur> AETDemandeurs { get; set; }
public DbSet<DestinatairePartageDocument> DestinatairesPartageDocuments { get; set; }
public DbSet<WPFFetcher> WPFFetchers { get; set; }
public DbSet<ClientWPFFetcher> ClientsWPFFetchers { get; set; }
public DbSet<ExamenAEnvoyer> ExamensAEnvoyer { get; set; }
public DbSet<ImageAEnvoyer> ImagesAEnvoyer { get; set; }
public DbSet<WorkerLocal> WorkersLocal { get; set; }
public DbSet<DestinationHL7> DestinationsHL7 { get; set; }
public DbSet<MessageHL7> MessagesHL7 { get; set; }
public DbSet<Patient> Patients { get; set; }
public DbSet<Examen> Examens { get; set; }
public DbSet<Medecin> Medecins { get; set; }
public DbSet<Correspondant> Correspondants { get; set; }
public DbSet<ExamensCorrespondants> ExamensCorrespondants { get; set; }
public DbSet<MappingHL7> MappingHL7 { get; set; }
public DbSet<ConfigurationWorker> ConfigurationWorker { get; set; }
public DbSet<DocumentStatus> DocumentStatus { get; set; }
public DbSet<Document> Documents { get; set; }
public DbSet<DocumentLogEvents> DocumentLogEvents { get; set; }
public DbSet<DestinatairePartage> DestinatairesPartage { get; set; }
public DbSet<Client> Clients { get; set; }
public DbSet<Revendeur> Revendeurs { get; set; }
public DbSet<ClientWorkerLocal> ClientWorkersLocal { get; set; }
public DbSet<DataProtectionKey> DataProtectionKeys { get; set; }
public DbSet<MappingExamenCompression> MappingExamenCompression { get; set; }
}
Has anyone any idea how to prevent this error from happening ?
I have tried changing the onDelete constraint but it didn't change anything.
Thanks for your help !
After clearing the table everything works fine.
I think I had foreign key id from my previous tests that didn't exist anymore in the original table.
Sorry to bother you !
I get this error:
Introducing FOREIGN KEY constraint may cause cycles or multiple cascade paths. Specify ON DELETE NO ACTION or ON UPDATE NO ACTION, or modify other FOREIGN KEY constraints.
What is the problem in my code?
public class AppUserMap : IEntityTypeConfiguration<AppUser>
{
public void Configure(EntityTypeBuilder<AppUser> builder)
{
builder.Property(m => m.Name).HasMaxLength(50).IsRequired(true);
builder.HasMany(m => m.Essays).WithOne(m => m.AppUser).HasForeignKey(m => m.AppUserId);
}
}
public class AppRoleMap : IEntityTypeConfiguration<AppRole>
{
public void Configure(EntityTypeBuilder<AppRole> builder)
{
builder.HasKey(m => m.Id);
builder.HasMany(m => m.AppUsers).WithOne(m => m.AppRole).HasForeignKey(m => m.AppRoleId).OnDelete(DeleteBehavior.NoAction);
}
}
public class AppRole : IdentityRole<int>, ITable
{
public List<AppUser> AppUsers { get; set; }
}
public class AppUser : IdentityUser<int>, ITable
{
public string Name { get; set; }
public string Picture { get; set; } = "default.png";
#nullable enable
public string? AppUserRole { get; set; }
#nullable disable
public bool Ban { get; set; } = false;
public List<Essay> Essays { get; set; }
public AppRole AppRole { get; set; }
public int AppRoleId { get; set; }
}
Thank you for answering. I solved the issue by changing a couple of things in my code.
This is my solution code(you can see the changes):
public class AppUser : IdentityUser<int>, ITable
{
public string Name { get; set; }
public string Picture { get; set; } = "default.png";
public bool Ban { get; set; } = false;
public List<Essay> Essays { get; set; }
#nullable enable
public AppRole? AppRole { get; set; }
public int? AppRoleId { get; set; }
#nullable disable
}
public class AppRoleMap : IEntityTypeConfiguration<AppRole>
{
public void Configure(EntityTypeBuilder<AppRole> builder)
{
builder.HasKey(m => m.Id);
builder.HasMany(m => m.AppUsers).WithOne(m => m.AppRole).HasForeignKey(m => m.AppRoleId).OnDelete(DeleteBehavior.SetNull);
}
}
I'm having some problems trying to use the many-to-many relationship in EF Core 2.0. Here is me code:
Here are my entities:
User
public class User : IdentityUser
{
private User()
{
}
public String Name { get; private set; }
public ICollection<UserCourse> UserCourses { get; private set; }
public static User Create(string name, string username, string email)
{
var instance = new User
{
Id = Guid.NewGuid().ToString(),
};
instance.Update(name, username, email);
return instance;
}
public void Update(string name, string username, string email)
{
Name = name;
UserName = username;
Email = email;
}
public void Update(UserCreatingModel model)
{
this.UserName = model.Username;
this.Name = model.Name;
this.Email = model.Email;
}
public void Update(UserCourse userCourse)
{
if (UserCourses == null)
{
UserCourses = new List<UserCourse>() {userCourse};
}
else
{
UserCourses.Add(userCourse);
}
}
}
Course entity
public class Course
{
private Course() { }
public Guid Id { get; private set; }
public string Name { get; private set; }
public int Year { get; private set; }
public int Semester { get; private set; }
public List<Lesson> Lessons { get; private set; }
public ICollection<UserCourse> UserCourses { get; private set; }
public static Course Create(string name, int year, int semester, List<Lesson> lessons, List<User> professors)
{
var instance = new Course { Id = Guid.NewGuid() };
instance.Update(name, year, semester, lessons);
return instance;
}
public static Course Create(string name, int year, int semester)
{
var instance = new Course { Id = Guid.NewGuid() };
instance.Update(name, year, semester);
return instance;
}
public void Update(string name, int year, int semester, List<Lesson> lessons)
{
Name = name;
Year = year;
Semester = semester;
Lessons = lessons;
}
public void Update(string name, int year, int semester)
{
Name = name;
Year = year;
Semester = semester;
}
public void Update(UserCourse userCourse)
{
if (UserCourses == null)
{
UserCourses = new List<UserCourse>(){userCourse};
}
else
{
UserCourses.Add(userCourse);
}
}
public void Update(List<Lesson> lessons)
{
this.Lessons = lessons;
}
}
Join entity
public class UserCourse
{
private UserCourse() { }
public string UserId { get; private set; }
public User User { get; private set; }
public Guid CourseId { get; private set; }
public Course Course { get; private set; }
public static UserCourse CreateUserCourse(string userId, User user, Guid coursId, Course course)
{
var instance = new UserCourse
{
UserId = userId,
User = user,
CourseId = coursId,
Course = course
};
return instance;
}
}
This is my database context
public sealed class DatabaseContext : IdentityDbContext<User>, IDatabaseContext
{
public static readonly LoggerFactory MyLoggerFactory
= new LoggerFactory(new[] {new ConsoleLoggerProvider((_, __) => true, true)});
public DatabaseContext(DbContextOptions<DatabaseContext> options) : base(options)
{
Database.EnsureCreated();
}
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
=> optionsBuilder
.UseLoggerFactory(MyLoggerFactory) // Warning: Do not create a new ILoggerFactory instance each time
.EnableSensitiveDataLogging();
public new DbSet<User> Users { get; set; }
public DbSet<Course> Courses { get; set; }
public DbSet<Lesson> Lessons { get; set; }
public DbSet<UserCourse> UserCourses { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Entity<Lesson>()
.HasOne(p => p.Course)
.WithMany(b => b.Lessons)
.OnDelete(DeleteBehavior.Cascade);
modelBuilder.Entity<UserCourse>()
.HasKey(uc => new {uc.UserId, uc.CourseId});
modelBuilder.Entity<UserCourse>()
.HasOne(uc => uc.User)
.WithMany(u => u.UserCourses)
.HasForeignKey(uc => uc.UserId);
modelBuilder.Entity<UserCourse>()
.HasOne(uc => uc.Course)
.WithMany(c => c.UserCourses)
.HasForeignKey(uc => uc.CourseId);
}
}
This is the repository where I try to add the 2 existing entities user and course to the joining table with the method AddCoursToProfessor
public class CoursesRepository : ACrudRepository<Course, Guid>, ICoursesRepository
{
public CoursesRepository(IDatabaseContext databaseContext) : base(databaseContext)
{
}
public override IReadOnlyList<Course> GetAll() => _databaseContext.Courses.Include(c => c.Lessons).Include(p => p.UserCourses).ToList();
public override Course GetById(Guid id)
=> _databaseContext.Courses.Include(c => c.Lessons).AsNoTracking().FirstOrDefault(c => c.Id.Equals(id));
public void AddCoursToProfessor(string profId, Guid coursId)
{
var professor = _databaseContext.Users.Include(u => u.UserCourses).FirstOrDefault(u => u.Id.Equals(profId));
var course = GetById(coursId);
var profCourse = UserCourse.CreateUserCourse(profId, professor, coursId, course);
professor.Update(profCourse);
_databaseContext.Users.Update(professor);
_databaseContext.SaveChanges();
}
}
The problem seems to be that when trying to add in the joining table, EF tries to add the course entity into it's table again and I get primary key violation error. I tried different approaches and none of them seem to work. I tried adding directly in UserCourse table but that would try to add both entities into their own tables, I tried deleting the entities before adding them to the join table, that didn't work either. I ran out of ideas, if someone has other ideas, or dealt with similar situations that would be much of help.
I forgot to mention that if I try to add a course by it self or an user, that would work, they both would be added to their tables, so I don't think that the problem is with the DB but with the configuration of the many-to-many relatonship
Ok... so I recently solved the problem. The problem was generated by the GetCourseById method because I was getting the entity AsNoTracking. The entity was not under the EF scope so it tried to create it.
As far as I know here's how I implement a MTM model.
In this instance, there are 3 parameters to take note.
CurrencyPairId is not unique. its a 2-unique parameter.
CurrencyId and IsMain is unique.
This is a trading exchange-styled composite key. i.e. EURUSD
EUR => Main Pair, USD => Counter Pair.
The class
/// <summary>
/// Partial currency pair.
/// </summary>
public class PartialCurrencyPair
{
public long CurrencyId { get; set; }
public long CurrencyPairId { get; set; }
public bool IsMain { get; set; } = false;
public CurrencyPair CurrencyPair { get; set; }
public Currency Currency { get; set; }
}
Currency
public class Currency : BaseEntityModel
{
[Key]
public long Id { get; set; }
public ICollection<PartialCurrencyPair> PartialCurrencyPairs { get; set; }
}
CurrencyPair
public class CurrencyPair : BaseEntityModel
{
[Key]
public long Id { get; set; }
// =========== RELATIONS ============ //
public ICollection<PartialCurrencyPair> PartialCurrencyPairs { get; set; }
}
Some of the mappings
in Currency;
entity.HasMany(c => c.PartialCurrencyPairs).WithOne(pcp => pcp.Currency).HasForeignKey(pcp => pcp.CurrencyId).OnDelete(DeleteBehavior.Restrict);
in CurrencyPair
entity.HasMany(cp => cp.PartialCurrencyPairs).WithOne(pcp => pcp.CurrencyPair).HasForeignKey(pcp => pcp.CurrencyPairId).OnDelete(DeleteBehavior.Restrict);
PartialCurrencyPair
builder.Entity<PartialCurrencyPair>(entity =>
{
entity.HasKey(pcp => new { pcp.CurrencyPairId, pcp.IsMain }).HasName("PartialCurrencyPair_CK_CurrencyPairId_IsMain");
});
Judging by your Course.cs, there's no Collection for UserCourse and why is it static?
Update, 2021 APR 6
EF Core has official documentation for the current practise for implementing MTM.
https://learn.microsoft.com/en-us/ef/core/modeling/relationships?tabs=fluent-api%2Cfluent-api-simple-key%2Csimple-key#many-to-many
I'am using EF6 and code firt in project, but i get this error on creating the model
Name: Each property name in a type must be unique. Property name 'varchar' is already defined.
below is my entity and my map
public class Menu
{
public Menu()
{
ListaFilhos = new List<Menu>();
}
public Int32 MenuID { get; set; }
public String Nome { get; set; }
public String Action { get; set; }
public String Controller { get; set; }
public String Url { get; set; }
public Int32? Pai { get; set; }
public Boolean? Ativo { get; set; }
public virtual List<Menu> ListaFilhos { get; set; }
}
Map
public class MenuMap : EntityTypeConfiguration<Entidade.Menu>
{
public MenuMap()
{
HasKey(x => x.MenuID);
Property(x => x.MenuID).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
Property(x => x.Pai).IsRequired();
Property(x => x.Nome).HasColumnType("varchar").HasMaxLength(100).IsRequired();
Property(x => x.Url).HasColumnName("varchar").HasMaxLength(250);
Property(x => x.Action).HasColumnName("varchar").HasMaxLength(50);
Property(x => x.Controller).HasColumnName("varchar").HasMaxLength(50);
Property(x => x.Ativo).IsRequired();
ToTable("Menu");
}
}
public class MenuGrupo
{
public MenuGrupo()
{
ListaMenu = new List<Menu>();
}
public Int32 MenuGrupoID { get; set; }
public Int32 MenuID { get; set; }
public virtual List<Menu> ListaMenu { get; set; }
}
public class MenuGrupoMap : EntityTypeConfiguration<Entidade.MenuGrupo>
{
public MenuGrupoMap()
{
HasKey(x => x.MenuGrupoID);
Property(x => x.MenuGrupoID).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
Property(x => x.MenuID).IsRequired();
ToTable("MenuGrupo");
}
}
I guess my problem is on MenuMap, when i remove in the OnModelCreate, all orther map working.
What i'am doing wrong?
tks
Im getting an error "Invalid column name 'FeeLevel_LevelId' which makes absolutely no sense considering all properties are simple types and there is no FeeLevel nor a LevelId object in this object.
So my context is:
public partial class FeesDbContext : DisconnectedEntityContext
{
public DbSet<Currency> Currencies { get; set; }
public DbSet<FeeLevel> FeeLevels { get; set; }
public DbSet<FeeLevelDetail> FeeLevelDetails { get; set; }
public DbSet<FeeType> FeeTypes { get; set; }
public DbSet<MemberFeeDiscountLevel> MemberFeeDiscountLevels { get; set; }
public FeesDbContext()
: base("FeesDb") { }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Configurations.Add(new FeeLevelMap());
modelBuilder.Configurations.Add(new FeeLevelDetailMap());
modelBuilder.Configurations.Add(new FeeTypeMap());
modelBuilder.Configurations.Add(new CurrencyMap());
modelBuilder.Configurations.Add(new MemberFeeDiscountLevelMap());
}
public static void ApplyChanges<TEntity>(TEntity root)
where TEntity : class, IObjectWithState
{
using (var context = new FeesDbContext())
{
context.Set<TEntity>().Add(root);
foreach (var entry in context.ChangeTracker.Entries<IObjectWithState>())
{
IObjectWithState stateInfo = entry.Entity;
entry.State = ConvertState(stateInfo.State);
}
context.SaveChanges();
}
}
}
The POCO is:
public partial class MemberFeeDiscountLevel : AbstractState
{
public long MemberFeeDiscountLevelId { get; set; }
public System.Guid MemberId { get; set; }
public short MemberAsType { get; set; }
public long FeeDiscountLevelId { get; set; }
public System.DateTime FeeDiscountLevelAppliedDate { get; set; }
public Nullable<System.DateTime> FeeDiscountLevelExpiresDate { get; set; }
public Nullable<long> FallbackFeeDiscountLevelId { get; set; }
public System.Guid UserId { get; set; }
public System.DateTime LastModified { get; set; }
public MemberFeeDiscountLevel(ObjectState state) : base(state) { }
public MemberFeeDiscountLevel()
{
}
}
It's mapping is:
public class MemberFeeDiscountLevelMap : EntityTypeConfiguration<MemberFeeDiscountLevel>
{
public MemberFeeDiscountLevelMap()
{
// Primary Key
this.HasKey(t => t.MemberFeeDiscountLevelId);
this.Ignore(t => t.State);
// Properties
// Table & Column Mappings
this.ToTable("MemberFeeDiscountLevel");
this.Property(t => t.MemberFeeDiscountLevelId).HasColumnName("MemberFeeDiscountLevelId");
this.Property(t => t.MemberId).HasColumnName("MemberId");
this.Property(t => t.MemberAsType).HasColumnName("MemberAsType");
this.Property(t => t.FeeDiscountLevelId).HasColumnName("FeeDiscountLevelId");
this.Property(t => t.FeeDiscountLevelAppliedDate).HasColumnName("FeeDiscountLevelAppliedDate");
this.Property(t => t.FeeDiscountLevelExpiresDate).HasColumnName("FeeDiscountLevelExpiresDate");
this.Property(t => t.FallbackFeeDiscountLevelId).HasColumnName("FallbackFeeDiscountLevelId");
this.Property(t => t.UserId).HasColumnName("UserId");
this.Property(t => t.LastModified).HasColumnName("LastModified");
}
}
The database table is:
and it has not relationships. Yet EF is generating the following SQL:
exec sp_executesql N'INSERT [dbo].[MemberFeeDiscountLevel]([MemberId], [MemberAsType], [FeeDiscountLevelId], [FeeDiscountLevelAppliedDate], [FeeDiscountLevelExpiresDate], [FallbackFeeDiscountLevelId], [UserId], [LastModified], [FeeLevel_LevelId])
VALUES (#0, #1, #2, #3, #4, #5, #6, #7, #8, NULL)
SELECT [MemberFeeDiscountLevelId]
FROM [dbo].[MemberFeeDiscountLevel]
WHERE ##ROWCOUNT > 0 AND [MemberFeeDiscountLevelId] = scope_identity()',N'#0 uniqueidentifier,#1 smallint,#2 bigint,#3 datetime2(7),#4 datetime2(7),#5 bigint,#6 uniqueidentifier,#7 datetime2(7),#8 int',#0='DAF771D1-079F-4743-B5C7-FD0FA1C63E19',#1=0,#2=1012,#3='2014-01-24 12:05:36.0608347',#4='2014-02-01 00:00:00',#5=1018,#6='EEDF2C83-2123-4B1C-BF8D-BE2D2FA26D09',#7='2014-01-24 12:05:36.0608347'
go
UPDATE:
Creating a new Fees2DbContext stripping out the other DbSets "fixes" the problem.... but I dont know why... none of these classes / sets are related to the class in question.
public partial class Fees2DbContext : DisconnectedEntityContext
{
public DbSet<MemberFeeDiscountLevel> MemberFeeDiscountLevels { get; set; }
public Fees2DbContext()
: base("FeesDb") { }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Configurations.Add(new MemberFeeDiscountLevelMap());
}
public static void ApplyChanges<TEntity>(TEntity root)
where TEntity : class, IObjectWithState
{
using (var context = new Fees2DbContext())
{
context.Set<TEntity>().Add(root);
foreach (var entry in context.ChangeTracker.Entries<IObjectWithState>())
{
IObjectWithState stateInfo = entry.Entity;
entry.State = ConvertState(stateInfo.State);
}
context.SaveChanges();
}
}
}
UPDATE 2:
public partial class FeeLevel : AbstractState
{
public FeeLevel()
{
this.FeeLevelDetails = new List<FeeLevelDetail>();
this.MemberFeeDiscountLevels = new List<MemberFeeDiscountLevel>();
}
public long LevelId { get; set; }
public string LevelName { get; set; }
public int CurrencyId { get; set; }
public System.DateTime LastModified { get; set; }
public bool IsSystemOwned { get; set; }
public System.Guid UserId { get; set; }
public virtual Currency Currency { get; set; }
[ScriptIgnore]
public virtual ICollection<FeeLevelDetail> FeeLevelDetails { get; set; }
public virtual ICollection<MemberFeeDiscountLevel> MemberFeeDiscountLevels { get; set; }
}
public class FeeLevelMap : EntityTypeConfiguration<FeeLevel>
{
public FeeLevelMap()
{
// Primary Key
this.HasKey(t => t.LevelId);
this.Ignore(t => t.State);
// Properties
this.Property(t => t.LevelId);
// .HasDatabaseGeneratedOption(DatabaseGeneratedOption.None);
this.Property(t => t.LevelName)
.IsRequired()
.HasMaxLength(50);
// Table & Column Mappings
this.ToTable("FeeLevel");
this.Property(t => t.LevelId).HasColumnName("LevelId");
this.Property(t => t.LevelName).HasColumnName("LevelName");
this.Property(t => t.CurrencyId).HasColumnName("CurrencyId");
this.Property(t => t.LastModified).HasColumnName("LastModified");
this.Property(t => t.UserId).HasColumnName("UserId");
// Relationships
this.HasRequired(t => t.Currency)
.WithMany(t => t.FeeLevels)
.HasForeignKey(d => d.CurrencyId);
}
}
FeeLevel.MemberFeeDiscountLevels is a navigation property and it introduces a one-to-many relationship between FeeLevel and MemberFeeDiscountLevel: A FeeLevel can have many MemberFeeDiscountLevels which means at the same time that a MemberFeeDiscountLevel has a single FeeLevel. Although you don't have a navigation and foreign key property in MemberFeeDiscountLevel the database must have a foreign key in the MemberFeeDiscountLevel table in order to model this relationship. EF assumes a default FK name as "related entity name+underscore+primary key name" = FeeLevel_LevelId. Because your database table doesn't have this column you get the exception.