まず、長い投稿をお詫び申し上げます。詳細を説明すると、状況を理解するのに役立つと思いました。
EF 5コードファーストを使用してアプリケーションのデータレイヤーを開発し、すべてを既存のデータベースにマッピングしようとしています。DbContext、POCO、流暢なテーブルマッピングなどを使用したいのですが、既存のデータベース(テーブル)は単純ではありません。だから、私はいくつかの問題を抱えています。ここで状況を簡単に説明し、後でいくつか質問します。
テーブル
AlarmDefinition
AlarmDefinitionID int (primary key) (is identity)
...
Alarm
AlarmID int (primary key) (is identity)
AlarmDefinitionID int (sort of a foreign key) (is nullable)
SampleTagID int (is nullable)
SampleTime DateTime (is nullable)
...
ReasonAction
Time DateTime (primary key)
TagID int (primary key)
ReasonActionID int (primary key)
ReasonActionDefinition
ReasonActionID int (primary key) (is identity)
...
したがって、1つのAlarmDefinitionに多数のアラームを含めることができます。また、1つのReasonActionDefinitionに多くのReasonActionを含めることができます。AlarmとReasonActionの間には暗黙の関係があります(つまり、1つのAlarmに多くのReasonActionを含めることができます)。これが私が最も問題を抱えているところです。
POCO
AlarmDefinition
public class AlarmDefinition
{
public int AlarmDefinitionID { get; set; }
...
public virtual ICollection<Alarm> Alarms { get; set; }
}
Alarm
public class Alarm
{
public int AlarmID { get; set; }
public Nullable<int> SampleTagID { get; set; }
public Nullable<System.DateTime> SampleTime { get; set; }
...
public Nullable<int> AlarmDefinitionID { get; set; }
public virtual AlarmDefinition AlarmDefinition { get; set; }
// I don’t know if this is set up correctly
public virtual ICollection<ReasonAction> ReasonActions { get; set; }
}
ReasonAction
public class ReasonAction
{
public System.DateTime Time { get; set; }
public int TagID { get; set; }
public virtual Alarm Alarm { get; set; }
public int ReasonActionID { get; set; } // Primary key
public virtual ReasonActionDefinition ReasonActionDefinition { get; set; }
}
ReasonActionDefinition
public class ReasonActionDefinition
{
public int ReasonActionID { get; set; }
...
public virtual ICollection<ReasonAction> ReasonActions { get; set; }
}
DbContext
public class AppDbContext : DbContext
{
public DbSet<Alarm> Alarms { get; set; }
public DbSet<AlarmDefinition> AlarmDefinitions { get; set; }
public DbSet<ReasonAction> ReasonActions { get; set; }
public DbSet<ReasonActionDefinition> ReasonActionDefinitions { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Configurations.Add(new AlarmMap());
modelBuilder.Configurations.Add(new AlarmDefinitionMap());
modelBuilder.Configurations.Add(new ReasonActionMap());
modelBuilder.Configurations.Add(new ReasonActionDefinitionMap());
}
}
流暢なマッピング
AlarmDefinitionMap
public class AlarmDefinitionMap : EntityTypeConfiguration<AlarmDefinition>
{
public AlarmDefinitionMap()
{
this.HasKey(t => t.AlarmDefinitionID);
...
this.ToTable("AlarmDefinition");
this.Property(t => t.AlarmDefinitionID).HasColumnName("AlarmDefinitionID");
...
}
}
AlarmMap
public class AlarmMap : EntityTypeConfiguration<Alarm>
{
public AlarmMap()
{
this.HasKey(t => t.AlarmID);
...
this.ToTable("Alarm");
this.Property(t => t.AlarmID).HasColumnName("AlarmID");
this.Property(t => t.AlarmDefinitionID).HasColumnName("AlarmDefinitionID");
this.Property(t => t.SampleTagID).HasColumnName("SampleTagID");
this.Property(t => t.SampleTime).HasColumnName("SampleTime");
...
this.HasOptional(t => t.AlarmDefinition)
.WithMany(d => d.Alarms)
.HasForeignKey(t => t.AlarmDefinitionID);
}
}
ReasonActionMap
public class ReasonActionMap : EntityTypeConfiguration<ReasonAction>
{
public ReasonActionMap()
{
this.HasKey(t => new { t.Time, t.TagID, t.ReasonActionID });
this.Property(t => t.TagID).HasDatabaseGeneratedOption(DatabaseGeneratedOption.None);
this.Property(t => t.ReasonActionID).HasDatabaseGeneratedOption(DatabaseGeneratedOption.None);
this.ToTable("ReasonAction");
this.Property(t => t.Time).HasColumnName("Time");
this.Property(t => t.TagID).HasColumnName("TagID");
this.Property(t => t.ReasonActionID).HasColumnName("ReasonActionID");
// Relationships
// Not sure if this is correct since the related column names in the Alarm table are SampleTagId, not TagID and SampleTime, not Time. And SampleTagID and SampleTime in the Alarm table are not a primary keys.
// There's an implicit one-to-many relationship between the Alarm and ReasonAction entities.
this.HasRequired(t => t.Alarm)
.WithMany(d => d.ReasonActions)
.HasForeignKey(t => new { t.TagID, t.Time });
this.HasRequired(t => t.ReasonActionDefinition)
.WithMany(d => d.ReasonActions)
.HasForeignKey(t => t.ReasonActionID);
}
}
ReasonActionDefinitionMap
public class ReasonActionDefinitionMap : EntityTypeConfiguration<ReasonActionDefinition>
{
public ReasonActionDefinitionMap()
{
this.HasKey(t => t.ReasonActionID);
...
this.ToTable("ReasonActionDefinition");
this.Property(t => t.ReasonActionID).HasColumnName("ReasonActionID");
...
}
}
ふぅ!それはたくさんのことでした。とにかく、データベースとEFへのマッピングに関するいくつかの問題があります。1。宣言型の参照整合性がない–すべてトリガーまたはレガシーアプリケーションコードで処理されます。2。アラームテーブルでは、SampleTagIDとSampleTimeはプライマリキーではありませんが、これら2つの列は、ReasonActionテーブルとの暗黙的な1対多の関係の片側です。3。AlarmsテーブルとReasonActionテーブルの間の列名が一致しません(AlarmテーブルのSampleTagIDとSampleTime、およびReasonActionテーブルのTimeとTagID)。
したがって、私の質問は次のとおりです。A.上記の状況で、EFコードを最初に既存のデータベースとテーブルで機能させることはできますか?B。コードを変更して1対多の関係を機能させるにはどうすればよいですか? AlarmテーブルとReasonActionテーブル(Alarmsをクエリすると、ReasonActionsナビゲーションプロパティに関連するすべてのレコードが入力されます)?、C。その他の提案はありますか?
ありがとう!!!