![](/img/trans.png)
[英]Creating composite primary key consisting off foreign keys in fluent API with ASP.NET core
[英]ASP.NET EF CORE: Composite key composed of two foreign keys not evaluating properly
編輯經過一些編輯后,我現在可以發布數據,但在搭建結構時遇到問題。 我的模型構建器現在感覺好多了,但還是有些不對勁
modelBuilder.Entity<Client>().HasMany(x => x.Machines).WithOne(x=>x.Client).HasForeignKey(x=>x.ClientID);
modelBuilder.Entity<Machine>().HasKey(x => new { x.ID, x.ClientID });
modelBuilder.Entity<MachineBob>().HasOne(x => x.Machine).WithMany(x => x.MachineBobData).HasForeignKey(x => new { x.MachineID, x.ClientID }).OnDelete(DeleteBehavior.NoAction);
modelBuilder.Entity<MachineMixer>().HasOne(x => x.Machine).WithMany(x => x.MachineMixerData).HasForeignKey(x => new { x.MachineID, x.ClientID }).OnDelete(DeleteBehavior.NoAction);
modelBuilder.Entity<MachineBob>().HasKey(c => new { c.TimeStamp, c.ClientID, c.MachineID });
modelBuilder.Entity<MachineMixer>().HasKey(x => new { x.TimeStamp, x.MachineID, x.ClientID });
結束 - 編輯
我正在嘗試使用 EF Core 構建一個 Web 應用程序,該應用程序將允許客戶端擁有任意數量的機器並記錄其數據。 每台機器都可以是不同的類型,並且每種類型的機器都有一個唯一的表,因為它們記錄不同的內容。 我能夠毫無困難地創建 Client 和 Machine 對象,但是一旦我嘗試將數據記錄到我的 Machinexxx 數據表中,我就會遇到有關使用復合外鍵的問題。
CloudApp.Models
public class Client
{
[Required]
[MaxLength(100)]
public string ClientName { get; set; }
[MaxLength(100)]
[Key]
public int ID { get; set; }
[MaxLength(100)]
// TODO: Automatically assign these email addresses as CLAIMS to allow the USER to see the CLIENT
public List<String> Emails;
public ICollection<Machine>? Machines { get; set; }
}
它與這里的Machine
類有一對多的關系
public class Machine
{
[MaxLength(50)]
[Key]
public int ID { get; set; }
[MaxLength(100)]
public string Factory { get; set; }
[MaxLength(50)]
public string Line { get; set; }
[MaxLength(50)]
public string MachineType { get; set; }
[MaxLength(50)]
public string MachineName { get; set; }
[MaxLength(50)]
public string Country { get; set; }
[MaxLength(50)]
public string City { get; set; }
[MaxLength(25)]
public int ZipCode { get; set; }
[MaxLength(50)]
public string Address { get; set; }
[MaxLength(50)]
public int ClientID { get; set; }
public Client Client { get; set; } // Navivation property
public List<MachineBob>? MachineBobData { get; set; } // Navivation property
public List<MachineMixer>? MachineMixerData { get; set; }// Navivation property
它與(當前)兩種可能的機器類型有一對多的關系
public class MachineBob
{
[MaxLength(50)]
[XmlElement("TimeStamp")]
public DateTime TimeStamp { get; set; }
[XmlElement("Temperature")]
[MaxLength(50)]
public int Temperature { get; set; }
[MaxLength(50)]
[XmlElement("Heartbeat")]
public Boolean Heartbeat { get; set; }
[MaxLength(50)]
[ForeignKey("MachineID")]
public int MachineID { get; set; }
public Machine Machine { get; set; }
[MaxLength(50)]
[ForeignKey("ClientID")]
public int ClientID { get; set; }
public Client Client { get; set; }
}
[XmlRoot("Root"),Serializable]
public class MachineMixer
{
[MaxLength(50)]
[XmlElement("TimeStamp")]
public DateTime TimeStamp { get; set; }
[XmlElement("Temperature")]
[MaxLength(50)]
public int MixingRatio { get; set; }
[MaxLength(50)]
[XmlElement("Heartbeat")]
public Boolean Heartbeat { get; set; }
[XmlIgnore]
[MaxLength(50)]
public int MachineID { get; set; }
public Machine Machine { get; set; }
[MaxLength(50)]
public int ClientID { get; set; }
public Client Client { get; set; }
}
最后我的模型構建器看起來像這樣(我的所有關系都在這里建立,由於它們的限制,我盡量不使用數據注釋)
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
foreach (var foreignKey in modelBuilder.Model.GetEntityTypes().SelectMany(e => e.GetForeignKeys()))
{
foreignKey.DeleteBehavior = DeleteBehavior.Cascade;
}
modelBuilder.Entity<Client>().HasMany(x => x.Machines);
modelBuilder.Entity<Machine>().HasOne(x => x.Client).WithMany(x => x.Machines).HasForeignKey(x => x.ClientID);
modelBuilder.Entity<Machine>().HasKey(x => new { x.ClientID, x.ID });
modelBuilder.Entity<Machine>().HasMany(x => x.MachineBobData).WithOne(x => x.Machine).HasForeignKey(x => new { x.MachineID, x.ClientID })OnDelete(DeleteBehavior.NoAction);
modelBuilder.Entity<Machine>().HasMany(x => x.MachineMixerData).WithOne(x => x.Machine).HasForeignKey(x => new { x.MachineID, x.ClientID }).OnDelete(DeleteBehavior.NoAction);
modelBuilder.Entity<MachineBob>().HasKey(c => new { c.TimeStamp, c.ClientID, c.MachineID });
modelBuilder.Entity<MachineMixer>().HasKey(x => new { x.TimeStamp, x.MachineID, x.ClientID });
}
我想要做的是讓每一行都是一個數據條目,具有一個由MachineID, ClientID, Timestamp
組成的唯一復合鍵。 但正如我在下面解釋的那樣,目前不可能......
正如我之前所說的,客戶端和機器類的所有 CRUD 操作都可以正常工作。 但是 MachineBob 是令人難以置信的問題。 即使模型設計看到存在三個元素的復合鍵,但每當我嘗試寫入表時,我都會收到 SQL 錯誤。 很奇怪的是,只要我使用 ClientID = 1、MachineID = 1 和我想要的唯一時間戳,我就可以按預期編寫。 但是,一旦我嘗試通過寫入 Client ID=X 來添加此 Machine BOB 的另一行或另一個實例,問題就會開始出現。
這是 SQL 異常,它似乎只有 ClientId 不唯一的問題。 但它是復合鍵的一部分,所以無論如何都不應該發生問題:
SqlException: INSERT 語句與 FOREIGN KEY 約束“FK_MachineBobs_Clients_ClientID”沖突。 數據庫“aspnet-ProcessCloudApp-B3DBF3A9-F26C-41F4-B7D6-CC2D2782C266”、表“dbo.Clients”、“ID”列中發生沖突。 該語句已終止。
我想要一些關於我的模型構建的幫助,因為我對此感到最迷茫。
我的一部分認為問題也可能在於我如何考慮這個“MachineBob”數據模型。 也許最好在“Machine”和“MachineBob”之間建立一對一的關系並擁有ICollection<T>
或List<T>
類型的所有屬性
謝謝您的幫助。
我能夠解決這個問題(只花了整周時間)。 我相應地修改了我的模型構建器,但也擺脫了 MachineBOB 中的“公共客戶端客戶端”。 即使我需要 ClientID,對象也沒有直接相互連接。 這是供其他人參考的代碼,他們認為值得進一步批評或供他們自己在這種半復雜關系中使用。
modelBuilder.Entity<Client>().HasMany(x => x.Machines).WithOne(x=>x.Client).HasForeignKey(x=>x.ClientID);
modelBuilder.Entity<Client>().HasKey(x => x.ID);
modelBuilder.Entity<Machine>().HasKey(x => new { x.ID, x.ClientID });
modelBuilder.Entity<MachineBob>().HasOne(x => x.Machine).WithMany(x => x.MachineBobData).HasForeignKey(x => new { x.MachineID, x.ClientID}).OnDelete(DeleteBehavior.NoAction);
modelBuilder.Entity<MachineMixer>().HasOne(x => x.Machine).WithMany(x => x.MachineMixerData).HasForeignKey(x => new { x.MachineID, x.ClientID }).OnDelete(DeleteBehavior.NoAction);
modelBuilder.Entity<MachineBob>().HasKey(c => new { c.TimeStamp, c.ClientID, c.MachineID });
modelBuilder.Entity<MachineMixer>().HasKey(x => new { x.TimeStamp, x.MachineID, x.ClientID });
和班級
[XmlRoot("Root"),Serializable]
public class MachineBob
{
[MaxLength(50)]
[XmlElement("TimeStamp")]
public DateTime TimeStamp { get; set; }
[XmlElement("Temperature")]
[MaxLength(50)]
public int Temperature { get; set; }
[MaxLength(50)]
[XmlElement("Heartbeat")]
public Boolean Heartbeat { get; set; }
[MaxLength(50)]
[ForeignKey("MachineID")]
public int MachineID { get; set; }
public Machine Machine { get; set; }
[MaxLength(50)]
[ForeignKey("ClientID")]
public int ClientID { get; set; }
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.