I dont know alot of English Lang But I will try...
so i have this error
Introducing FOREIGN KEY constraint 'FK_Conversation_User_Users_UserID' on table 'Conversation_User' may cause
cycles or multiple cascade paths.
Specify ON DELETE NO ACTION or ON UPDATE NO ACTION, or modify other FOREIGN KEY constraints.
and my code is:
AppDB:
public class AppDB : DbContext
{
public AppDB() : base() { }
public AppDB(DbContextOptions<AppDB> options) : base(options) { }
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder.UseSqlServer(#"Server=(LocalDB)\MSSQLLocalDB;Database=TetraMessangerDB;Trusted_Connection=True;");
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Conversation_User>().HasKey(cu => new { cu.ConversationID, cu.UserID });
modelBuilder.Entity<Message_Media>().HasKey(mm => new { mm.MediaID, mm.MessageID });
modelBuilder.Entity<Participant>().HasKey(p => new { p.UserID, p.GroupID });
}
public DbSet<User> Users { get; set; }
public DbSet<Conversation_User> Conversation_User { get; set; }
public DbSet<Conversation> Conversation { get; set; }
}
User:
public class User
{
public User()
{
Participants = new List<Participant>();
SenMessages = new List<Message>();
ResMessages = new List<Message>();
}
public int UserID { get; set; }
public string Name { get; set; }
public string Password { get; set; }
public string Bio { get; set; }
public string EMail { get; set; }
public string UserName { get; set; }
public bool Activate { get; set; }
public int MediaID { get; set; }
public virtual Media Media { get; set; }
public virtual UserStatus UserStatus { get; set; }
public virtual List<Participant> Participants { get; set; }
[InverseProperty("SenderUser")]
public virtual List<Message> SenMessages { get; set; }
[InverseProperty("ReciverUser")]
public virtual List<Message> ResMessages { get; set; }
public virtual List<Conversation_User> Conversation_User { get; set; }
}
Conversation:
public class Conversation
{
public Conversation()
{
Conversation_User = new List<Conversation_User>();
}
public int ConversationID { get; set; }
public DateTime StartDate { get; set; }
public int MediaID { get; set; }
public virtual Media Media { get; set; }
public virtual List<Conversation_User> Conversation_User { get; set; }
}
Conversation_User:
public class Conversation_User
{
public int ConversationID { get; set; }
public virtual Conversation Conversation { get; set; }
public int UserID { get; set; }
public virtual User User { get; set; }
}
so I see alot of same quastion but i dont understand ...
i dont have multiple path so why i get this error.
can some body explain this.
Note: I have alot of entitys with the same problem in Many-To-Many Relationship but if i can solve this, I will understand how to solve thim.
and thanks for helping me.
Edit: I tried this but still getting the same
modelBuilder.Entity<Conversation_User>()
.HasOne(pt => pt.User)
.WithMany(p => p.Conversation_User)
.HasForeignKey(pt => pt.UserID)
.IsRequired()
.OnDelete(DeleteBehavior.NoAction);
modelBuilder.Entity<Conversation_User>()
.HasOne(pt => pt.Conversation)
.WithMany(p => p.Conversation_User)
.HasForeignKey(pt => pt.ConversationID)
.IsRequired()
.OnDelete(DeleteBehavior.NoAction);
Related
I have 4 classes in dbcontext,it's EventRemind.cs Event.cs House.cs Customer.cs,the code like this:
public class EventRemind
{
[Key]
public Guid Id { get; set; }
public Guid CustomerEventId { get; set; }
public DateTime RemindTime { get; set; }
public bool HasRead { get; set; }
public DateTime CreatedTime { get; set; }
[ForeignKey("CustomerEventId")]
public virtual Event CustomerEvent { get; set; }
}
public class Event
{
[Key]
public Guid Id { get; set; }
public string Title { get; set; }
public int UserId { get; set; }
public int HouseId { get; set; }
[MaxLength(800)]
public string Content { get; set; }
public DateTime CreatedTime { get; set; }
[ForeignKey("HouseId")]
public virtual House House { get; set; }
[ForeignKey("UserId")]
public virtual Customer Customer { get; set; }
public virtual ICollection<EventRemind> EventReminds { get; set; }
}
public class House
{
public int Id { get; set; }
public string Name { get; set; }
public virtual ICollection<Event> HouseEvents { get; set; }
}
public class Customer
{
public int Id { get; set; }
public string Name { get; set; }
public virtual ICollection<Event> CustomerEvents { get; set; }
}
and my dbcontext is this:
public class DataContext:DbContext
{
public DataContext(DbContextOptions options) : base(options)
{
}
public DbSet<EventRemind> EventReminds { get; set; }
public DbSet<Event> Events { get; set; }
public DbSet<House> Houses { get; set; }
public DbSet<Customer> Customers { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
}
}
that means an eventRemind include an event,an event include a house and a customer,now what puzzles me is that what should I do to get the House and Customer at the same time from EventReminds,what I want is this:
var query = _dataContext.EventReminds.Include(c => c.CustomerEvent)
.ThenInclude(c => c.Customer).ThenInclude(c => c.House //this get a compile error);
why dis this happen? Can somebody help me? Thanks in advance.
I think your last operator should be just Include. Try this:
var query = _dataContext.EventReminds
.Include(c => c.CustomerEvent)
.ThenInclude(c => c.Customer)
.Include(c => c.House);
You have to write code following way.
Way1
var query =
_dataContext.EventReminds.Include(c => c.CustomerEvent).ThenInclude(c => c.Customer)
.Include(c=> c.CustomerEvent).ThenInclude(c => c.House);
Way2 (If property is not collection then it is usefull)
var query =
_dataContext.EventReminds.Include(c=> c.CustomerEvent).
.Include(c=> c.CustomerEvent.Customer)
.Include(c=> c.CustomerEvent.House);
I'm trying to straighten out the EF-Model for a junctiontable OwnerCows.dbo.
There's a class Cow with an Id, a class Owner with an Id and i want to reference them both in a OwnerCows-table that has only an OwnerCowId, a CowId(FK) and a OwnerId(FK).
The error I'm getting is:
Cannot create a relationship between 'Owner.OwnerCows' and 'OwnerCow.Owner', because there already is a relationship between 'Owner.CowOwners' and 'OwnerCow.Owner'. Navigation properties can only participate in a single relationship.
Does it mean I have a circular reference? How can I solve this?
the Owner.cs:
public class Owner : EntityBase<Guid>
{
public string Name { get; set; }
[NotMapped]
public ICollection<Cow> Cows { get; set; }
= new List<Cow>();
public virtual List<OwnerCow> CowOwners { get; set; }
public Cow Cow { get; set; }
}
the Cow.cs:
public class Cow : EntityBase<Guid>
{
[MaxLength(50)]
public string Name { get; set; }
public string Breed { get; set; }
public string Color { get; set; }
public ICollection<Entities.Weight> Weights { get; set; }
= new List<Weight>();
public ICollection<Vaccination> Vaccinations { get; set; }
= new List<Vaccination>();
[NotMapped]
public ICollection<Owner> CowOwners { get; set; }
= new List<Owner>();
public List<OwnerCow> OwnerCows { get; set; }
}
the OwnerCows.cs:
public class OwnerCow
{
public Guid OwnerCowId { get; set; }
public Cow Cow { get; set; }
public Guid CowId { get; set; }
public Owner Owner { get; set; }
public Guid OwnerId { get; set; }
}
the Context-class:
public class DogFaceContext : DbContext
{
public DogFaceContext()
{
}
public DogFaceContext(DbContextOptions<DogFaceContext> options)
: base(options)
{
Database.Migrate();
}
//Entity Tables
public virtual DbSet<Owner> Owners { get; set; }
public virtual DbSet<Cow> Cows { get; set; }
public virtual DbSet<Vaccination> Vaccination { get; set; }
public virtual DbSet<Weight> Weight { get; set; }
//Junction Tables
public virtual DbSet<OwnerCow> OwnerCows { get; set; }
protected override void OnModelCreating(ModelBuilder builder)
{
base.OnModelCreating(builder);
builder.Entity<Cow>().HasMany(x => x.CowOwners).WithOne(x => x.Cow);
builder.Entity<Owner>().HasMany(u => u.CowOwners).WithOne(X => X.Owner);
builder.Entity("DogFace.API.Entities.OwnerCow", b =>
{
b.HasOne("DogFace.API.Entities.Cow", "Cow")
.WithMany("OwnerCows")
.HasForeignKey("CowId")
.OnDelete(DeleteBehavior.Restrict);
b.HasOne("DogFace.API.Entities.Owner", "Owner")
.WithMany("OwnerCows")
.HasForeignKey("OwnerId")
.OnDelete(DeleteBehavior.Restrict);
});
}
}
Can I get it to work with this design? Is it possible with EFCore? Any other suggestions? Thanks!
You model is very complex and has some unnecessary relationships like Owner.Cows since you decide to configure many-to-many relationship.You could just get Owner's cows using
var owner = new Owner();
List<Cow> cows = owner.OwnerCows.Where(oc => oc.OwnerId == owner.Id)
.Select(oc => oc.Cow)
.ToList();
1.To have OwnerCowId, a CowId(FK) and a OwnerId(FK) in OwnerCows, refer to my below configuration:
public class Owner : EntityBase<Guid>
{
public string Name { get; set; }
public virtual List<OwnerCow> OwnerCows { get; set; }
}
public class Cow : EntityBase<Guid>
{
[MaxLength(50)]
public string Name { get; set; }
public string Breed { get; set; }
public string Color { get; set; }
public ICollection<Entities.Weight> Weights { get; set; } = new List<Weight>();
public ICollection<Vaccination> Vaccinations { get; set; }= new List<Vaccination>();
public List<OwnerCow> OwnerCows { get; set; }
}
public class OwnerCow
{
[Key]
public Guid OwnerCowId { get; set; }
public Cow Cow { get; set; }
public Guid CowId { get; set; }
public Owner Owner { get; set; }
public Guid OwnerId { get; set; }
}
DbContext:
protected override void OnModelCreating(ModelBuilder builder)
{
base.OnModelCreating(builder);
builder.Entity<OwnerCow>()
.HasOne(oc => oc.Cow)
.WithMany(c => c.OwnerCows)
.HasForeignKey(oc => oc.CowId);
builder.Entity<OwnerCow>()
.HasOne(oc => oc.Owner)
.WithMany(o => o.OwnerCows)
.HasForeignKey(oc => oc.OwnerId);
}
}
In this case, your OwnerCowId id the primary key for your OwnerCows table which is not reasonable and it may have the same record of CowId,OwnerId for OwnerCows.
2.Usually,the primary key for the join table is a composite key comprising both of the foreign key values,I suggest that you could use composite key for your OwnerCow:
public class OwnerCow
{
public Cow Cow { get; set; }
public Guid CowId { get; set; }
public Owner Owner { get; set; }
public Guid OwnerId { get; set; }
}
DbContext:
protected override void OnModelCreating(ModelBuilder builder)
{
base.OnModelCreating(builder);
builder.Entity<OwnerCow>()
.HasKey(oc => new { oc.OwnerId, oc.CowId });
builder.Entity<OwnerCow>()
.HasOne(oc => oc.Cow)
.WithMany(c => c.OwnerCows)
.HasForeignKey(oc => oc.CowId);
builder.Entity<OwnerCow>()
.HasOne(oc => oc.Owner)
.WithMany(o => o.OwnerCows)
.HasForeignKey(oc => oc.OwnerId);
}
}
Refer to https://www.learnentityframeworkcore.com/configuration/many-to-many-relationship-configuration
Fix context builder:
protected override void OnModelCreating(ModelBuilder builder)
{
base.OnModelCreating(builder);
builder.Entity<Cow>().HasMany(x => x.CowOwners).WithOne(x => x.Cow);
builder.Entity<Owner>().HasMany(u => u.Cows).WithOne(X => X.Owner); // Cows instead of CowOwners
builder.Entity("DogFace.API.Entities.OwnerCow", b =>
{
b.HasOne("DogFace.API.Entities.Cow", "Cow")
.WithMany("OwnerCows")
.HasForeignKey("CowId")
.OnDelete(DeleteBehavior.Restrict);
b.HasOne("DogFace.API.Entities.Owner", "Owner")
.WithMany("CowOwners") // CowOwners instead of OwnerCows
.HasForeignKey("OwnerId")
.OnDelete(DeleteBehavior.Restrict);
});
}
... or fix property names in classes:
public class Owner : EntityBase<Guid>
{
public string Name { get; set; }
[NotMapped]
public ICollection<Cow> CowOwners { get; set; } // CowOwners instead of Cows ?
= new List<Cow>();
public virtual List<OwnerCow> OwnerCow { get; set; } // OwnerCow instead of CowOwners ?
public Cow Cow { get; set; }
}
but don't forget to change dbcontext builder with fixed property names.
How fix the problem ?
Error Message
In Entity Framework Core, I'm attempting to create a system with 4 Db Models - User,UserProfile,Review, ApplicationInfo.
I tried a lot of things, well, I don’t understand the concept of how to fix the situation, I clearly gave cascade in modelOnCreate
Model User.
public class User
{
public int Id { get; set; }
public string Email { get; set; }
public string Password { get; set; }
public string Token { get; set; }
public UserProfile UserProfile { get; set; }
}
Model UserProfile
public class UserProfile
{
public int Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string Phone { get; set; }
public int UserId { get; set; }
public User User { get; set; }
public IEnumerable<ApplicationInfo> ApplicationInfos { get; set; }
public IEnumerable<Review> Reviews { get; set; }
}
Model Review
public class Review
{
public int Id { get; set; }
public string Text { get; set; }
public string ImageLocation { get; set; }
public string Version { get; set; }
public string Rate { get; set; }
//One(AppInfo) to Many(Review)
public int ApplicationInfoId { get; set; }
public ApplicationInfo ApplicationInfo { get; set; }
//One(UserProfile) to Many(Review)
public int UserProfileId { get; set; }
[Required]
public UserProfile UserProfile { get; set; }
}
Model ApplicationInfo
public class ApplicationInfo
{
[Key]
public int Id { get; set; }
[Required]
public string ApplicationId { get; set; }
[Required]
public string AppName { get; set; }
[Required]
public string PublisherEmail { get; set; }
public string Genre { get; set; }
public string Price { get; set; }
public string Description { get; set; }
public string Version { get; set; }
public string IconUrl { get; set; }
public string PublisherName { get; set; }
public string AllRatingCount { get; set; }
public string AllRating { get; set; }
//One(UserProfile) To Many(AppInfo)
public int UserProfileId { get; set; }
public UserProfile UserProfile { get; set; }
public IEnumerable<Review> Reviews { get; set; }
}
OnModelCreating
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<User>().
HasOne<UserProfile>(s=>s.UserProfile).
WithOne(s=>s.User).
HasForeignKey<UserProfile>(s=>s.UserId)
.OnDelete(DeleteBehavior.Cascade);
modelBuilder.Entity<ApplicationInfo>()
.HasOne<UserProfile>(s => s.UserProfile)
.WithMany(s => s.ApplicationInfos)
.OnDelete(DeleteBehavior.Cascade);
modelBuilder.Entity<Review>()
.HasOne<UserProfile>(s => s.UserProfile)
.WithMany(s => s.Reviews)
.OnDelete(DeleteBehavior.Cascade);
modelBuilder.Entity<Review>()
.HasOne<ApplicationInfo>(s => s.ApplicationInfo)
.WithMany(s => s.Reviews)
.OnDelete(DeleteBehavior.Cascade);
}
Just Change OnModelCreating and change OnDelete for Review and AppInfo to Restrict(No Action)
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<User>()
.HasOne<UserProfile>(s => s.Profile)
.WithOne(s => s.User)
.HasForeignKey<UserProfile>(s=>s.UserId)
.OnDelete(DeleteBehavior.Cascade);
modelBuilder.Entity<ApplicationInfo>()
.HasOne<UserProfile>(s => s.UserProfile)
.WithMany(s => s.ApplicationInfos)
.HasForeignKey(s => s.UserProfileId)
.OnDelete(DeleteBehavior.Cascade);
modelBuilder.Entity<Review>()
.HasOne<UserProfile>(s => s.UserProfile)
.WithMany(s => s.Reviews)
.HasForeignKey(s => s.UserProfileId)
.OnDelete(DeleteBehavior.Restrict);
modelBuilder.Entity<Review>()
.HasOne<ApplicationInfo>(s => s.ApplicationInfo)
.WithMany(s => s.Reviews)
.HasForeignKey(s => s.ApplicationInfoId)
.OnDelete(DeleteBehavior.Restrict);
base.OnModelCreating(modelBuilder);
}
I am getting all the related tables populated (multiple times /circular/loop) even for a simple include of 2 tables query..
Here are my DB details.
public interface IPhaniDbContext
{
DbSet<Data_CustomerDetail> CustomerDetails { get; set; }
DbSet<Data_DisplayStyle> DisplayStyles { get; set; }
DbSet<Data_ResumeDetail> ResumeDetails { get; set; }
int Save();
Task<int> SaveChangesAsync();
Database Database { get; }
DbEntityEntry Entity(object entity);
DbSet<TEntity> Set<TEntity>() where TEntity : class;
}
public class PhaniDbContext :DbContext , IPhaniDbContext
{
public PhaniDbContext() : base(ConnectionString())
{
Configuration.LazyLoadingEnabled = false;
}
private static string ConnectionString()
{
return ConfigurationManager.AppSettings[Constants.Appsetting_PhaniDbConnectionString];
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Configurations.AddFromAssembly(Assembly.GetAssembly(GetType()));
modelBuilder.Entity<Data_CustomerDetail>()
.HasMany(x => x.ResumeDetails).WithRequired(e => e.CustomerDetail).WillCascadeOnDelete(false);
//modelBuilder.Entity<Data_CustomerDetail>()
// .Map(x => x.Requires("ResumeDetails")).Ignore(e => e.ResumeDetails)
// .Map(x => x.Requires("DisplayStyle")).Ignore(e => e.ResumeDetails);
modelBuilder.Entity<Data_DisplayStyle>()
.HasMany(x => x.ResumeDetails).WithRequired(e => e.DisplayStyle).WillCascadeOnDelete(false);
}
public int Save()
{
return base.SaveChanges();
}
public DbEntityEntry Entity(object entity)
{
throw new NotImplementedException();
}
//TODO: No-Urget-Over ride Save just to know. and all other possible overrides.
public virtual DbSet<Data_CustomerDetail> CustomerDetails { get; set; }
public virtual DbSet<Data_DisplayStyle> DisplayStyles { get; set; }
public virtual DbSet<Data_ResumeDetail> ResumeDetails { get; set; }
}
Query:
_phaniDbContext.CustomerDetails
.Include(x => x.ResumeDetails)
.Include(x=>x.ResumeDetails.Select(y=>y.DisplayStyle))
.First(x=>x.CustomerDetailsID == customerId);
My pocos are here:
[Table("CustomerDetails")]
public class Data_CustomerDetail
{
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
public Data_CustomerDetail()
{
ResumeDetails = new HashSet<Data_ResumeDetail>();
}
[Key]
public int CustomerDetailsID { get; set; }
[StringLength(500)]
public string FirstName { get; set; }
[StringLength(500)]
public string LastName { get; set; }
[StringLength(50)]
public string phoneNumber { get; set; }
[StringLength(50)]
public string Zipcode { get; set; }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<Data_ResumeDetail> ResumeDetails { get; set; }
}
public class Data_DisplayStyle
{
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
public Data_DisplayStyle()
{
ResumeDetails = new HashSet<Data_ResumeDetail>();
}
public int DisplayStyleID { get; set; }
[StringLength(500)]
public string Name { get; set; }
[StringLength(500)]
public string Description { get; set; }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<Data_ResumeDetail> ResumeDetails { get; set; }
}
[Table("ResumeDetails")]
public class Data_ResumeDetail
{
[Key]
public int ResumeDetailsId { get; set; }
[Column("CAREER OBJECTIVE")]
[StringLength(4000)]
public string CAREER_OBJECTIVE { get; set; }
[Column("HONORS AND REWARDS")]
[StringLength(4000)]
public string HONORS_AND_REWARDS { get; set; }
[Column("PROFESSIONAL RESPONSIBILITIES")]
[StringLength(4000)]
public string PROFESSIONAL_RESPONSIBILITIES { get; set; }
[Column("RELATED EXPERIENCE")]
[StringLength(4000)]
public string RELATED_EXPERIENCE { get; set; }
public int? CustomerDetailsID { get; set; }
public int? DisplayStyleId { get; set; }
public virtual Data_CustomerDetail CustomerDetail { get; set; }
public virtual Data_DisplayStyle DisplayStyle { get; set; }
}
Could someone please help me in resolving this...
I just want CustomerDetails and ResumeDetails and displaystyle table once... not multiple times..
This is increasing my object weight
When doing a foreign key relationship, you probably need to specify the foreign key(s)
Example:
modelBuilder
.Entity<Data_CustomerDetail>()
.HasMany(x => x.ResumeDetails)
.WithRequired(e => e.CustomerDetail)
.HasForeignKey(e => e.CustomerDetailsID)
.WillCascadeOnDelete(false);
modelBuilder
.Entity<Data_DisplayStyle>()
.HasMany(x => x.ResumeDetails)
.WithRequired(e => e.DisplayStyle)
.HasForeignKey(e => e.DisplayStyleId)
.WillCascadeOnDelete(false);
I have next entity configuration:
public class OfficesContext : DbContext
{
public DbSet<Office> Offices { get; set; }
public DbSet<Expense> Expenses { get; set; }
public DbSet<ExpenseLog> ExpenseLogs { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<Office>()
.Property(o => o.OfficeId)
.HasDatabaseGeneratedOption(DatabaseGeneratedOption.None);
modelBuilder.Entity<Expense>()
.Property(o => o.ExpenseId)
.HasDatabaseGeneratedOption(DatabaseGeneratedOption.None);
modelBuilder.Entity<Office>()
.HasMany(o => o.Expenses)
.WithMany()
.Map(mc =>
{
mc.ToTable("ExpenseLogs");
mc.MapLeftKey("ExpenseId");
mc.MapRightKey("OfficeId");
});
}
}
public class Office
{
public Office()
{
ExpenseLogs = new HashSet<ExpenseLog>();
Expenses = new HashSet<Expense>();
}
public int OfficeId { get; set; }
public string Name { get; set; }
public ICollection<ExpenseLog> ExpenseLogs { get; private set; }
public ICollection<Expense> Expenses { get; private set; }
}
public class Expense
{
public Expense()
{
ExpenseLogs = new HashSet<ExpenseLog>();
Offices = new HashSet<Office>();
}
public int ExpenseId { get; set; }
public string Name { get; set; }
public ICollection<ExpenseLog> ExpenseLogs { get; private set; }
public ICollection<Office> Offices { get; private set; }
}
public class ExpenseLog
{
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int ExpenseLogId { get; set; }
public int OfficeId { get; set; }
public Office Office { get; set; }
public int ExpenseId { get; set; }
public Expense Expense { get; set; }
public DateTime InputDate { get; set; }
public decimal Amoun { get; set; }
public string Description { get; set; }
}
But it creates two tables for expences logs ExpenseLogs and ExpenseLogs1. ExpenseLogs has only foreign keys ExpenseId and OfficeId. ExpenseLogs1 has same fields as in class ExpenseLog. I also tried to use next mappings but it doesnt helped:
modelBuilder.Entity<ExpenseLog>().HasRequired(e => e.Office);
modelBuilder.Entity<ExpenseLog>().HasRequired(e => e.Expense);
You have some redundant configuration Try these changes:
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<Office>()
.Property(o => o.OfficeId)
.HasDatabaseGeneratedOption(DatabaseGeneratedOption.None);
modelBuilder.Entity<Expense>()
.Property(o => o.ExpenseId)
.HasDatabaseGeneratedOption(DatabaseGeneratedOption.None);
// ** this is redundant - ef will figure it from the bridge class **
// modelBuilder.Entity<Office>()
// .HasMany(o => o.Expenses)
// .WithMany()
// .Map(mc =>
// {
// mc.ToTable("ExpenseLogs");
// mc.MapLeftKey("ExpenseId");
// mc.MapRightKey("OfficeId");
// });
}
public class Office
{
public Office()
{
ExpenseLogs = new HashSet<ExpenseLog>();
Expenses = new HashSet<Expense>();
}
public int OfficeId { get; set; }
public string Name { get; set; }
public ICollection<ExpenseLog> ExpenseLogs { get; private set; }
// access offices thru ExpenseLogs
// public ICollection<Expense> Expenses { get; private set; }
}
public class Expense
{
public Expense()
{
ExpenseLogs = new HashSet<ExpenseLog>();
Offices = new HashSet<Office>();
}
public int ExpenseId { get; set; }
public string Name { get; set; }
public ICollection<ExpenseLog> ExpenseLogs { get; private set; }
// access offices thru ExpenseLogs
// public ICollection<Office> Offices { get; private set; }
}
See Create code first, many to many, with additional fields in association table