Прежде всего извинения, это вопрос ладьи ie.
Я пытаюсь написать программу c#, которая подключается к существующей базе данных и изменяет определенные значения на основе пользовательского ввода. (Я знаю, это может звучать как плохая идея, но у нас есть свои причины…) Я решил использовать ядро ef для подключения к базе данных.
System.InvalidOperationException: 'Дочерняя / зависимая сторона не может быть определена для отношения «один к одному» между «Dad.DadCmu» и «DadCmu.IddadNavigation». Чтобы определить дочернюю / зависимую сторону отношения, настройте свойство внешнего ключа. Если эти переходы не должны быть частью одного и того же отношения, настройте их без указания обратного. См. http://go.microsoft.com/fwlink/?LinkId=724062 для более подробной информации. Давайте теперь посмотрим на классы:
public partial class DadCmu
{
public int Iddad { get; set; }
public byte UnitNo { get; set; }
public virtual Dad IddadNavigation { get; set; }
}
Итак, IddadNavigation имеет тип Dad:
public partial class Dad
{
public Dad()
{
DadCh = new HashSet<DadCh>();
DadConnection = new HashSet<DadConnection>();
}
public int Iddad { get; set; }
public string Name { get; set; }
public int? DadType { get; set; }
public short? Active { get; set; }
public DateTime? LastUpdate { get; set; }
public byte? SynchronizationStatus { get; set; }
public virtual DadCmu DadCmu { get; set; }
public virtual DadMasCon DadMasCon { get; set; }
public virtual DadOpc DadOpc { get; set; }
public virtual ICollection<DadCh> DadCh { get; set; }
public virtual ICollection<DadConnection> DadConnection { get; set; }
}
И их отношения должны быть определены в OnModelCreating
:
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
…
modelBuilder.Entity<DadCmu>(entity =>
{
entity.HasKey(e => e.Iddad);
entity.ToTable("DadCMU");
entity.Property(e => e.Iddad)
.HasColumnName("IDDad")
.ValueGeneratedNever();
entity.HasOne(d => d.IddadNavigation)
.WithOne(p => p.DadCmu)
.HasForeignKey<DadCmu>(d => d.Iddad)
.HasConstraintName("FK_DadCMU_Dad");
});
…
modelBuilder.Entity<Dad>(entity =>
{
entity.HasKey(e => e.Iddad);
entity.Property(e => e.Iddad).HasColumnName("IDDad");
entity.Property(e => e.LastUpdate).HasColumnType("datetime");
});
…
}
Итак, в modelBuilder.Entity<DadCmu>
явно упоминается внешний ключ, поэтому я не совсем уверен, в чем проблема? Должен ли я сделать то же самое в modelBuilder.Entity<Dad>
?
Как бы выглядел этот код?
Или я неправильно понимаю проблему?
Это то, что может быть сделано автоматически, например, с параметром для scaffold-dbcontext
? (В моей БД 180 таблиц, и я получаю ту же ошибку для многих из них.)
И возможно ли все это без изменения структуры самой БД?
Большое спасибо в Advance ! Опять же, я впервые работаю с базами данных, поэтому извиняюсь, если это действительно очевидно.
Редактировать: Класс DadOp c, который появился в комментариях:
public partial class DadOpc
{
public int Iddad { get; set; }
public string Computer { get; set; }
public string OpcserviceName { get; set; }
public float? ScanInterval { get; set; }
public byte? ServerType { get; set; }
public byte? UseSecurity { get; set; }
public virtual Dad IddadNavigation { get; set; }
}
Правка 2: (относительно решения jcruz)
Сообщение об ошибке:
System.InvalidOperationException: 'Дочерний / зависимый сторона не может быть определена для отношения «один к одному» между «DadMasCon.IddadNavigation» и «Dad.DadMasCon». Чтобы определить дочернюю / зависимую сторону отношения, настройте свойство внешнего ключа. Если эти переходы не должны быть частью одного и того же отношения, настройте их без указания обратного. См. http://go.microsoft.com/fwlink/?LinkId=724062 для более подробной информации. '
Класс Dad:
public partial class Dad
{
public Dad()
{
DadCh = new HashSet<DadCh>();
DadConnection = new HashSet<DadConnection>();
}
//user added Id-Fields:
public int DadCmuId { get; set; }
public int DadOpcId { get; set; }
public int DadMasConId { get; set; }
public int Iddad { get; set; }
public string Name { get; set; }
public int? DadType { get; set; }
public short? Active { get; set; }
public DateTime? LastUpdate { get; set; }
public byte? SynchronizationStatus { get; set; }
public virtual DadCmu DadCmu { get; set; }
public virtual DadMasCon DadMasCon { get; set; }
public virtual DadOpc DadOpc { get; set; }
public virtual ICollection<DadCh> DadCh { get; set; }
public virtual ICollection<DadConnection> DadConnection { get; set; }
}
Класс DadMasCon:
public DadMasCon()
{
DadModbusRegConfig = new HashSet<DadModbusRegConfig>();
}
public int Iddad { get; set; }
public int UnitNo { get; set; }
public byte? Model { get; set; }
public DateTime? RefTimeOffset { get; set; }
public float? TimeoutComm { get; set; }
public int? Port { get; set; }
public float? ConnectionInterval { get; set; }
public byte? ExternalComm { get; set; }
public string Mvbparameters { get; set; }
public byte? ModbusBps { get; set; }
public byte? ModbusParity { get; set; }
public byte? ModbusStopBits { get; set; }
public byte? ModbusMode { get; set; }
public byte? ModbusSlaveAddress { get; set; }
public byte? CardType0 { get; set; }
public byte? CardType1 { get; set; }
public byte? CardType2 { get; set; }
public byte? CardType3 { get; set; }
public string LastIp { get; set; }
public string HiddenParameter { get; set; }
public int? SerialNo { get; set; }
public int? LastSequence { get; set; }
public int? TcppackageErrors { get; set; }
public byte? UsePrivateFirmware { get; set; }
public byte? ConfigurationLock { get; set; }
public byte? IecclientOn { get; set; }
public string IecclientAddress { get; set; }
public string IecclientDomain { get; set; }
public byte? IecsrvOn { get; set; }
public byte? IecsrvNrOfClents { get; set; }
public string IecsrvAuthentication { get; set; }
public string Iecmmsparam { get; set; }
public float? IecclientPollInterval { get; set; }
public byte? NtpserverType { get; set; }
public string Ntpipaddress { get; set; }
public string IecmmsparamFileName { get; set; }
public string ModbusTcpaddress { get; set; }
public int? ModbusTcpportNr { get; set; }
public byte? ModbusByteOrder { get; set; }
public byte? ModbusClientValueType { get; set; }
public string Macaddress { get; set; }
public byte? MonitorInitiate { get; set; }
public virtual Dad IddadNavigation { get; set; }
public virtual ICollection<DadModbusRegConfig> DadModbusRegConfig { get; set; }
}
OnModelCreating:
modelBuilder.Entity<DadMasCon>(entity =>
{
entity.HasKey(e => e.Iddad)
.HasName("PK_DadMasCon16");
entity.Property(e => e.Iddad)
.HasColumnName("IDDad")
.ValueGeneratedNever();
entity.Property(e => e.IecclientAddress).HasColumnName("IECClientAddress");
entity.Property(e => e.IecclientDomain).HasColumnName("IECClientDomain");
entity.Property(e => e.IecclientOn).HasColumnName("IECClientOn");
entity.Property(e => e.IecclientPollInterval).HasColumnName("IECClientPollInterval");
entity.Property(e => e.Iecmmsparam).HasColumnName("IECMMSParam");
entity.Property(e => e.IecmmsparamFileName).HasColumnName("IECMMSParamFileName");
entity.Property(e => e.IecsrvAuthentication).HasColumnName("IECSrvAuthentication");
entity.Property(e => e.IecsrvNrOfClents).HasColumnName("IECSrvNrOfClents");
entity.Property(e => e.IecsrvOn).HasColumnName("IECSrvOn");
entity.Property(e => e.Macaddress).HasColumnName("MACAddress");
entity.Property(e => e.ModbusTcpaddress)
.HasColumnName("ModbusTCPAddress")
.HasMaxLength(50);
entity.Property(e => e.ModbusTcpportNr).HasColumnName("ModbusTCPPortNr");
entity.Property(e => e.Mvbparameters).HasColumnName("MVBParameters");
entity.Property(e => e.Ntpipaddress).HasColumnName("NTPIPAddress");
entity.Property(e => e.NtpserverType).HasColumnName("NTPServerType");
entity.Property(e => e.RefTimeOffset).HasColumnType("datetime");
entity.Property(e => e.TcppackageErrors).HasColumnName("TCPPackageErrors");
//user generated:
entity.HasOne(d => d.IddadNavigation)
.WithOne(p => p.DadMasCon)
.HasForeignKey<Dad>(d => d.DadMasConId);
//original:
//entity.HasOne(d => d.IddadNavigation)
// .WithOne(p => p.DadMasCon)
// .HasForeignKey<DadMasCon>(d => d.Iddad)
// .HasConstraintName("FK_DadMasCon_Dad");
});