I'm building Reporting system, but having problem with removing data from db.
public class Report
{
[Key]
public int ReportId { get; set; }
public string Title { get; set; }
public int? DateRange { get; set; }
public int Layout { get; set; }
public DateTime? DateFrom { get; set; }
public DateTime? DateTo { get; set; }
public int OwnerId { get; set; }
public DateTime DateCreated { get; set; }
public bool Active { get; set; }
public virtual List<ReportCharts> ReportCharts { get; set; }
public virtual List<ReportElements> ReportElements { get; set; }
}
public class ReportElements
{
[Key, Column(Order = 1)]
public int ReportId { get; set; }
[Key, Column(Order = 2)]
public string ElementName { get; set; }
public Boolean Active { get; set; }
}
public class ReportCharts
{
[Key, Column(Order = 1)]
public int ReportId { get; set; }
[Key, Column(Order = 2)]
public string ChartId { get; set; }
public Boolean Active { get; set; }
}
In DbContext:
public DbSet<Report> Reports { get; set; }
// Report entity mapping
protected virtual void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<Report>().Property(t => t.ReportId).HasColumnName("ReportId");
modelBuilder.Entity<Report>().Property(t => t.Title).HasColumnName("Title");
modelBuilder.Entity<Report>().Property(t => t.DateRange).HasColumnName("DateRange");
modelBuilder.Entity<Report>().Property(t => t.Layout).HasColumnName("Layout");
modelBuilder.Entity<Report>().Property(t => t.DateFrom).HasColumnName("DateFrom");
modelBuilder.Entity<Report>().Property(t => t.DateTo).HasColumnName("DateTo");
modelBuilder.Entity<Report>().Property(t => t.OwnerId).HasColumnName("OwnerId");
modelBuilder.Entity<Report>().Property(t => t.DateCreated).HasColumnName("DateCreated");
modelBuilder.Entity<Report>().Property(t => t.Active).HasColumnName("Active");
modelBuilder.Entity<Report>().HasMany(t => t.ReportElements).WithRequired().HasForeignKey(c => c.ReportId);
modelBuilder.Entity<Report>().HasMany(t => t.ReportCharts).WithRequired().HasForeignKey(p => p.ReportId);
modelBuilder.Entity<ReportElements>().Property(c => c.ElementName).HasColumnName("ElementName");
modelBuilder.Entity<ReportElements>().HasKey(c => new { c.ReportId, c.ElementName, c.Active });
modelBuilder.Entity<ReportCharts>().Property(p => p.ChartId).HasColumnName("ChartId");
modelBuilder.Entity<ReportCharts>().HasKey(c => new { c.ReportId, c.ChartId, c.Active });
}
In EF repository:
public void RemoveReport(Report rep)
{
context.Reports.Remove(rep);
context.SaveChanges();
}
When I perform delete it deletes only from Report table, and not from all three. When I do save report it saves in all three tables. So don't really understand what is wrong.
Many thanks for your help
You need to look into cascading delete options in Entity Framework an apply them as you need them.
Try this:
modelBuilder.Entity<Report>().HasMany(t => t.ReportElements)
.WithRequired()
.HasForeignKey(c => c.ReportId)
.WillCascadeOnDelete(true);
modelBuilder.Entity<Report>().HasMany(t => t.ReportCharts)
.WithRequired()
.HasForeignKey(p => p.ReportId)
.WillCascadeOnDelete(true);
Related
My entities classes that are used in the project:
public class Game
{
public int Id { get; set; }
public int FirstTeamId { get; set; }
public Team FirstTeam { get; set; }
public int SecondTeamId { get; set; }
public Team SecondTeam { get; set; }
public Stadium Stadium { get; set; }
public DateTime Date { get; set; }
public GameStatus Result { get; set; }
public Game(DateTime date , GameStatus result )
{
Date = date;
Result = result;
}
}
public class Player
{
public int Id { get; set; }
public string Name { get; set; }
public string Surname { get; set; }
public DateTime Birthday { get; set; }
public PlayerStatus Status { get; set; }
public PlayerHealthStatus HealthStatus { get; set; }
public int Salary { get; set; }
public int TeamId { get; set; }
public Team Team { get; set; }
public Player(string name , string surname, DateTime birthday, PlayerStatus status, PlayerHealthStatus healthStatus, int salary)
{
Name = name;
Surname = surname;
Birthday = birthday;
Status = status;
HealthStatus = healthStatus;
Salary = salary;
}
}
public class Stadium
{
public int Id { get; set; }
public string Name { get; set; }
public int Capacity { get; set; }
public int PriceForPlace { get; set; }
public Stadium(string name, int capacity, int priceForPlace)
{
Name = name;
Capacity = capacity;
PriceForPlace = priceForPlace;
}
}
public class Team
{
public int Id { get; set; }
public string Name { get; set; }
public List<Player> Players { get; set; }
public List<Game> Games { get; set; }
public Team(string name)
{
Name = name;
}
public Team(string name, List<Player> players) : this(name)
{
Players = players;
}
}
My EF Core context class:
public class ApplicationContext : DbContext
{
public DbSet<Player> Players { get; set; }
public DbSet<Game> Games { get; set; }
public DbSet<Team> Teams { get; set; }
public DbSet<Stadium> Stadiums { get; set; }
public ApplicationContext()
{
Database.EnsureCreated();
}
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder.UseSqlServer("Server=best-komp;Database=FootballApplicationDataBase;Trusted_Connection=True;");
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Player>()
.HasOne(p => p.Team)
.WithMany(t => t.Players)
.HasForeignKey(p => p.TeamId).OnDelete(DeleteBehavior.NoAction)
.HasPrincipalKey(t => t.Id);
modelBuilder.Entity<Team>()
.HasMany(t => t.Players)
.WithOne(p => p.Team)
.HasForeignKey(p => p.Id).OnDelete(DeleteBehavior.NoAction)
.HasPrincipalKey(t => t.Id);
modelBuilder.Entity<Game>()
.HasOne(g => g.HomeTeam)
.WithMany(t => t.HomeGames)
.HasForeignKey(t => t.HomeTeamId)
.HasPrincipalKey(t => t.Id);
modelBuilder.Entity<Game>()
.HasOne(g => g.AwayTeam)
.WithMany(t => t.AwayGames)
.HasForeignKey(t => t.AwayTeamId).OnDelete(DeleteBehavior.NoAction)
.HasPrincipalKey(t => t.Id);
}
}
But when I try to call my context class, like
var db = new ApplicationContext();
I can see that my team and player classes dont refer to each other.
All other classes have refer to team, like player have a team, game have a team. But my team classes dont have refer to any class, they have NULL instead a reference.
What is the problem?
Your Team configuration is incorrect. The foreign key should be TeamId not Id. As the FK on Players entity is TeamId.
modelBuilder.Entity<Team>()
.HasMany(t => t.Players)
.WithOne(p => p.Team)
.HasForeignKey(p => p.TeamId).OnDelete(DeleteBehavior.NoAction)
.HasPrincipalKey(t => t.Id);
Maybe try using ForeignKey annotations. First, add using statement:
using System.ComponentModel.DataAnnotations.Schema;
Then add a [ForeignKey("ModelName")] annotation above each foreign key. For example:
[ForeignKey("FirstTeam")]
public int FirstTeamId { get; set; }
public Team FirstTeam { get; set; }
[ForeignKey("SecondTeam")]
public int SecondTeamId { get; set; }
public Team SecondTeam { get; set; }
This makes foreign key relationships explicit that EF sometimes can't infer.
I have my entities like this, they are closely linked.
public class Game
{
public int Id { get; set; }
public int FirstTeamId { get; set; }
public Team FirstTeam { get; set; }
public int SecondTeamId { get; set; }
public Team SecondTeam { get; set; }
public Stadium Stadium { get; set; }
public DateTime Date { get; set; }
public GameStatus Result { get; set; }
public Game(DateTime date , GameStatus result )
{
Date = date;
Result = result;
}
}
public class Player
{
public int Id { get; set; }
public string Name { get; set; }
public string Surname { get; set; }
public DateTime Birthday { get; set; }
public PlayerStatus Status { get; set; }
public PlayerHealthStatus HealthStatus { get; set; }
public int Salary { get; set; }
public int TeamId { get; set; }
public Team Team { get; set; }
public Player(string name , string surname, DateTime birthday, PlayerStatus status, PlayerHealthStatus healthStatus, int salary)
{
Name = name;
Surname = surname;
Birthday = birthday;
Status = status;
HealthStatus = healthStatus;
Salary = salary;
}
}
public class Stadium
{
public int Id { get; set; }
public string Name { get; set; }
public int Capacity { get; set; }
public int PriceForPlace { get; set; }
public Stadium(string name, int capacity, int priceForPlace)
{
Name = name;
Capacity = capacity;
PriceForPlace = priceForPlace;
}
}
public class Team
{
public int Id { get; set; }
public string Name { get; set; }
public List<Player> Players { get; set; }
public List<Game> Games { get; set; }
public Team(string name)
{
Name = name;
}
public Team(string name, List<Player> players) : this(name)
{
Players = players;
}
}
In my Context class I'm tried to describe my relationships between classes. But something isn't correct.
public class ApplicationContext : DbContext
{
public DbSet<Player> Players { get; set; }
public DbSet<Game> Games { get; set; }
public DbSet<Team> Teams { get; set; }
public DbSet<Stadium> Stadiums { get; set; }
public ApplicationContext()
{
Database.EnsureCreated();
}
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder.UseSqlServer("Server=best-komp;Database=FootballApplicationDataBase;Trusted_Connection=True;");
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Player>()
.HasOne(p => p.Team)
.WithMany(t => t.Players)
.HasForeignKey(p => p.TeamId)
.HasPrincipalKey(t => t.Id);
modelBuilder.Entity<Team>()
.HasMany(p => p.Players)
.WithOne(p => p.Team)
.HasForeignKey(p => p.TeamId)
.HasPrincipalKey(t => t.Id);
modelBuilder.Entity<Game>()
.HasOne(g => g.FirstTeam)
.WithMany(t => t.Games)
.HasForeignKey(t => t.FirstTeamId)
.HasPrincipalKey(t => t.Id);
modelBuilder.Entity<Game>()
.HasOne(g => g.SecondTeam)
.WithMany(t => t.Games)
.HasForeignKey(t => t.SecondTeamId)
.HasPrincipalKey(t => t.Id);
}
}
What wrong with this code? Because I have "Navigation properties can only participate in a single relationship." error when I try to do something with my ApplicationContext.
You can't reuse Team.Games as the inverse property for both Game.FirstTeam and Team.SecondTeam. Think of it, if you add game to Team.Games, how would EF know which team it is, first or second?
You need two collections to describe the relationships. And that's also a chance to add some more meaning to the class model. For example (only modified code):
public class Game
{
...
public int HomeTeamId { get; set; }
public Team HomeTeam { get; set; }
public int AwayTeamId { get; set; }
public Team AwayTeam { get; set; }
}
public class Team
{
...
public List<Game> HomeGames { get; set; }
public List<Game> AwayGames { get; set; }
}
For a team it's meaningful to make a distinction between home and away games, for example to compare results in both types of games.
And the mapping:
modelBuilder.Entity<Game>()
.HasOne(g => g.HomeTeam)
.WithMany(t => t.HomeGames)
.HasForeignKey(t => t.HomeTeamId)
.HasPrincipalKey(t => t.Id);
modelBuilder.Entity<Game>()
.HasOne(g => g.AwayTeam)
.WithMany(t => t.AwayGames)
.HasForeignKey(t => t.AwayTeamId).OnDelete(DeleteBehavior.NoAction)
.HasPrincipalKey(t => t.Id);
If using Sql Server, this delete behavior instruction is necessary to prevent disallowed multiple cascade paths.
The problem is that your Team model has 2 one-to-many relationships with your Game model but you only have one navigation property on the Team.
You need to have 2 navigation properties on the Team model, one for each relationship.
(Game1, Game2...).
You will also need to define these relationships in the Game model - a Team property for each relationship.
Check this answer for extra info.
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);
}
Worked a lot with EF 6.x (via designer) and now started on a new project using EF Core.
I'm getting an error that says value cannot be null, not sure exactly what I'm doing wrong. I've got rid of a lot of fields for brevity as there are hundreds.
All these tables are views via synonyms that connect to a different database. I can get it to work fine, if I do each individual call to a database, but as soon as I do include. I get an error on that line. The error I'm getting is
ArgumentNullException: Value cannot be null.
Parameter name: key
System.Collections.Generic.Dictionary.FindEntry(TKey key)
OnGetAsync
var equipment = _context.EMEMs.Include(x => x.EMEDs).Where(x => x.KeyID.ToString() == key);
EMEM = await equipment.Include(x => x.EMCM).ThenInclude(x=>x.EMCDs).FirstOrDefaultAsync();
EMEM
public class EMEM
{
public byte? EMCo { get; set; }
[Display(Name = "Equipment Code")]
public string Equipment { get; set; }
public string Type { get; set; }
public string Category { get; set; }
public Guid? UniqueAttchID { get; set; }
[Key]
public long KeyID { get; set; }
[NotMapped] public string EquipmentDetails => $"{Equipment.Trim()} - {Description} - {VINNumber}";
public virtual IEnumerable<EMWH> EMWHs { get; set; }
public virtual EMCM EMCM { get; set; }
public virtual IEnumerable<udEMED> EMEDs { get; set; }
}
EMCM
public class EMCM
{
[Key]
public long KeyID { get; set; }
public byte? EMCo { get; set; }
public string Category { get; set; }
public string Description { get; set; }
public string Notes { get; set; }
public virtual IEnumerable<EMEM> EMEMs { get; set; }
public virtual IEnumerable<udEMCD> EMCDs { get; set; }
}
udEMCD
public class udEMCD
{
[Key]
public long KeyID { get; set; }
public byte? Co { get; set; }
public string Category { get; set; }
public string DocumentCategory { get; set; }
public int Seq { get; set; }
public Guid? UniqueAttchID { get; set; }
public virtual udEMDC EMDC { get; set; }
public virtual EMCM EMCM { get; set; }
public virtual IEnumerable<HQAT> HQATs { get; set; }
}
Context
modelBuilder.Entity<EMEM>().ToTable("EMEM").HasOne(x => x.EMCM).WithMany(x => x.EMEMs).HasForeignKey(x => new { x.EMCo, x.Category }).HasPrincipalKey(x => new { x.EMCo, x.Category });
modelBuilder.Entity<EMEM>().ToTable("EMEM").HasMany(x => x.EMEDs).WithOne(x => x.EMEM).HasForeignKey(x => new { x.Co, x.Equipment }).HasPrincipalKey(x => new { x.EMCo, x.Equipment });
modelBuilder.Entity<EMCM>().ToTable("EMCM").HasMany(x => x.EMCDs).WithOne(x => x.EMCM)
.HasForeignKey(x => new { x.Co, x.Category }).HasPrincipalKey(x => new { x.EMCo, x.Category });
modelBuilder.Entity<udEMCD>().ToTable("udEMCD").HasOne(x => x.EMDC).WithMany(x => x.EMCDs)
.HasForeignKey(x => x.DocumentCategory).HasPrincipalKey(x => x.Category);
modelBuilder.Entity<udEMDC>().ToTable("udEMDC").HasMany(x => x.EMEDs).WithOne(x => x.EMDC).HasForeignKey(x => new{ x.DocumentCategory}).HasPrincipalKey(x => new{ x.Category});
modelBuilder.Entity<udEMED>().ToTable("udEMED");
modelBuilder.Entity<EMWH>().ToTable("EMWH");
modelBuilder.Entity<EMWI>().ToTable("EMWI");
modelBuilder.Entity<HQAT>().HasOne(x => x.EMWH).WithMany(x => x.HQATs).HasForeignKey(x => x.UniqueAttchID)
.HasPrincipalKey(x => x.UniqueAttchID);
modelBuilder.Entity<EMWH>().HasOne(x => x.EMEM).WithMany(x => x.EMWHs)
.HasForeignKey(x => new {x.EMCo, x.Equipment}).HasPrincipalKey(x => new {x.EMCo, x.Equipment});
EDIT: I added nullable KeyID's just to test prior to uploading and still didn't work.
I think the error is that you're declaring the Key as nullable, which it should never happen.
[Key]
public long? KeyID { get; set; }
change your code to this...
[Key]
public long KeyID { get; set; }
This is a followup-question of this question, where i had a similar problem. But this is solved now by default foreign key convention.
My problem now is (in short), that my migrations generates
int ReferencedEntityID;
int ReferencedEntity_ReferencedEntityID;
where one is an integer property in my model and the other one is a virtual property.
My migrations generates this:
"dbo.Contracts",
c => new
{
ContractId = c.Int(nullable: false, identity: true),
PricePerUnit = c.Double(nullable: false),
Unit = c.Int(nullable: false),
Currency = c.Int(nullable: false),
ClientId = c.Int(nullable: false),
CompanyId = c.Int(nullable: false),
ArticleId = c.Int(nullable: false),
Client_ClientId = c.Int(),
Article_ArticleId = c.Int(),
})
As you can see, Client & Article are referenced twice.
Here are my models
public class Client {
public Client() { }
[Key]
public int ClientId { get; set; }
public string Number { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string ZipCode { get; set; }
public string City { get; set; }
public string AddressLine1 { get; set; }
public string AddressLine2 { get; set; }
public string Memo { get; set; }
public bool isMerchant { get; set; }
public string Name
{
get
{
return string.Format("{0} {1}", FirstName, LastName);
}
}
public int? MerchantReferenceId { get; set; }
public virtual Client MerchantReference { get; set; }
[Required]
public int CompanyId { get; set; }
public virtual Company Company { get; set; }
public virtual ICollection<Contract> Contracts { get; set; }
public virtual ICollection<Order> Orders { get; set; }
}
public class Article {
public Article() { }
[Key]
public int ArticleId { get; set; }
[Required]
public string Code { get; set; }
public string Name { get; set; }
public bool TrackStock { get; set; }
public int CurrentStock { get; set; }
public double? Price { get; set; }
[Required]
public int CompanyId { get; set; }
public virtual Company Company { get; set; }
[Required]
public int CategoryId { get; set; }
public virtual Category Category { get; set; }
public virtual ICollection<Contract> Contracts { get; set; }
public virtual ICollection<Order> Orders { get; set; }
}
public class Contract {
public Contract() { }
[Key]
public int ContractId { get; set; }
public double PricePerUnit { get; set; }
public int Unit { get; set; }
public int Currency { get; set; }
[Required]
public int ClientId { get; set; }
// [ForeignKey("ClientId")]
public virtual Client Client { get; set; }
[Required]
public int CompanyId { get; set; }
//[ForeignKey("CompanyID")]
public virtual Company Company { get; set; }
[Required]
public int ArticleId { get; set; }
// [ForeignKey("ArticleId")]
public virtual Article Article { get; set; }
}
Here is my OnModelCreating()
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
// modelBuilder.Entity<Contract>().HasRequired(bm => bm.Company).WithMany().WillCascadeOnDelete(false);
modelBuilder.Entity<Contract>().HasRequired(bm => bm.Article).WithMany().HasForeignKey(dl => dl.ArticleId).WillCascadeOnDelete(false);//.Map( dl => dl.MapKey("ArticleId"))
modelBuilder.Entity<Contract>().HasRequired(bm => bm.Client).WithMany().HasForeignKey(dl => dl.ClientId).WillCascadeOnDelete(false);//.Map(dl => dl.MapKey("ClientId"))
modelBuilder.Entity<Article>().HasRequired(bm => bm.Company).WithMany().HasForeignKey(dl => dl.CompanyId).WillCascadeOnDelete(false);//.Map(dl => dl.MapKey("CompanyId"))
modelBuilder.Entity<Measurement>().HasRequired(bm => bm.Company).WithMany().HasForeignKey(dl => dl.CompanyId).WillCascadeOnDelete(false); //.Map(dl => dl.MapKey("CompanyId"))
modelBuilder.Entity<Order>().HasRequired(bm => bm.Client).WithMany().HasForeignKey(dl => dl.ClientId).WillCascadeOnDelete(false); //.Map(dl => dl.MapKey("ClientId"))
modelBuilder.Entity<Order>().HasRequired(bm => bm.Article).WithMany().HasForeignKey(dl => dl.ArticleId).WillCascadeOnDelete(false);//.Map(dl => dl.MapKey("ArticleId"))
modelBuilder.Entity<IncomingMeasurement>().HasRequired(bm => bm.client).WithMany().HasForeignKey(dl => dl.ClientId).WillCascadeOnDelete(false);//.Map(dl => dl.MapKey("ClientId"))
modelBuilder.Entity<Client>().HasOptional(c => c.MerchantReference).WithMany().HasForeignKey(dl => dl.MerchantReferenceId); //.Map(dl => dl.MapKey("MerchantReferenceId"))
//Required fields
base.OnModelCreating(modelBuilder);
}
What do i have to do, to create them both:
Required
Both in one property in my db-schema (as it should)
It is OK, even recommended, to have primitive FK properties (like ArticleId) accompanying the "real" references. In EF this is called a foreign key association as opposed to an independent association where there is only a reference (like Article.Company).
So you can keep your model the way it is. You just have to specify the foreign keys.
I tried with a few classes in the model of your previous question and this produced the desired results:
modelBuilder.Entity<Article>().HasMany(a => a.Contracts)
.WithRequired(c => c.Article)
.HasForeignKey(c => c.ArticleID).WillCascadeOnDelete(false);
modelBuilder.Entity<Client>().HasMany(c => c.Contracts)
.WithRequired(c => c.Client)
.HasForeignKey(c => c.ClientID).WillCascadeOnDelete(false);
modelBuilder.Entity<Company>().HasMany(c => c.Articles)
.WithRequired(a => a.Company)
.HasForeignKey(c => c.CompanyID).WillCascadeOnDelete(false);
Note that I turned around the definitions because when I did it your way, but with HasForeignKey it still duplicated the FK fields. I'm not sure why.