РЕДАКТИРОВАТЬ После некоторого редактирования я теперь могу опубликовать данные, но у меня есть проблемы с созданием структуры. Мой модельер чувствует, что сейчас стало лучше, но что-то все еще не в порядке
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 });
END - EDIT
Я пытаюсь создать веб-приложение с использованием EF Core, которое будет разрешить клиенту владеть любым количеством машин и регистрировать их данные. Каждая машина может быть разного типа, и у каждого типа машины есть уникальная таблица, поскольку они регистрируют разные вещи. Я могу без проблем создать объект «Клиент и машина», но как только я пытаюсь записать данные в свои таблицы данных 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 для ботов класса Client и Machine работают нормально. Но MachineBob невероятно проблематичен c. Несмотря на то, что дизайн модели видит, что есть составной ключ из трех элементов, я получаю ошибку SQL всякий раз, когда пытаюсь записать в таблицу. Что очень странно, так это то, что я могу писать, как и ожидалось, при условии, что я использовал ClientID = 1, MachineID = 1 и уникальную метку времени, которая мне нужна. Но как только я пытаюсь добавить еще одну строку или другой экземпляр этой машины BOB, написав Client ID = X, начинают возникать проблемы.
Вот исключение SQL, которое, похоже, имеет проблему только с ClientId не быть уникальным. Но это часть составного ключа, поэтому проблема не должна возникать в любом случае:
SqlException: оператор INSERT конфликтует с ограничением FOREIGN KEY "FK_MachineBobs_Clients_ClientID". Конфликт произошел в базе данных «as pnet -ProcessCloudApp-B3DBF3A9-F26 C -41F4-B7D6-CC2D2782C266», таблица «dbo.Clients», столбец «ID». Утверждение было прекращено.
Я хотел бы получить некоторую помощь, касающуюся моего моделестроения, поскольку я чувствую себя наиболее потерянным с этим.
Часть меня чувствует, что проблема может также заключаться в том, как я Я думаю об этой модели данных "MachineBob". Возможно, было бы лучше вместо этого иметь отношение один к одному между «Машиной» и «Машинным бобом» и иметь все свойства типа ICollection<T>
или List<T>
Спасибо за вашу помощь.