0

MVC プロジェクトで (初めて) 注釈を付けてコードを作成しようとしています。

以下の POCO を作成しました。

[Table("Customers")]
public partial class Customer
{
    public int Id { get; set; }

    [Required]
    [DisplayName("First Name")]
    public string FirstName { get; set; }

    [DisplayName("Last Name")]
    [Required]
    public string LastName { get; set; }
    //other properties...
 }

[Table("Vehicles")]
public partial class Vehicle
{
    [Required]
    public int Id { get; set; }

    [Required]
    public int CustomerId { get; set; }

    [Required]
    public string Make { get; set; }

    [Required]
    public string Model { get; set; }

    [Required]
    public string Year { get; set; }

    //other fields
    [ForeignKey("CustomerId")]
    public virtual Customer Customer { get; set; }
}


[Table("CustomerAppointments")]
public partial class CustomerAppointment
{

    [Key,Column(Order=0)]
    public int CustomerId { get; set; }

    [Key,Column(Order=1)]
    public int VehicleId { get; set; }

    public DateTime? AppointmentDate { get; set; }

    public DateTime? AppointmentTime { get; set; }

    public string AvailableDays { get; set; }

    //other fields

    [ForeignKey("CustomerId")]
    public virtual Customer Customer { get; set; }

    [ForeignKey("VehicleId")]
    public virtual Vehicle Vehicle { get; set; }
}

ここでの私の意図はかなり明白だと思います。私には顧客がいます。それらの顧客は車を持っています。顧客と顧客の車両の 1 つがサービスのためにスケジュールされているテーブル CustomerAppointments を作成したいと考えています。

記録のために、これはモデル全体ではなく、質問のために単純化されています。

MvcScaffolding を使用して EF アイテムとビューを構築しています。

すべてがコンパイルされますが、顧客ページ (実際には、顧客を参照することは言及されていないクラス) に移動しようとすると、次のエラーが発生します...

Introducing FOREIGN KEY constraint 'FK_dbo.CustomerAppointments_dbo.Vehicles_VehicleId' on table 'CustomerAppointments' may cause cycles or multiple cascade paths. Specify ON DELETE NO ACTION or ON UPDATE NO ACTION, or modify other FOREIGN KEY constraints.

私はさまざまな注釈を試してみましたが、このようなもので流暢な API を使用しようとさえしました...

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
    modelBuilder.Entity<CustomerAppointment>()
        .HasRequired(ca => ca.Customer)
        .WithRequiredPrincipal()
        .WillCascadeOnDelete(false);

    modelBuilder.Entity<CustomerAppointment>()
        .HasRequired(ca => ca.Vehicle)
        .WithRequiredPrincipal()
        .WillCascadeOnDelete(false);

}

しかし、私はそれを機能させることができません。Google と SO で見つけたすべてのサンプルを読みましたが、役に立ちませんでした。

PS ...これが注釈のみで機能する場合、それが私の好みです。

4

3 に答える 3

2

モデルには、 aが削除されるCustomerまでの 2 つのカスケード削除パスがあります。CustomerAppointmentCustomer

  • Customer-> Vehicle->CustomerAppointment
  • Customer->CustomerAppointment

これは SQL Server では許可されておらず、例外が発生します。Fluent API でのみ可能なこれら 3 つのサブパスの少なくとも 1 つのカスケード削除を無効にする必要があります。たとえば、Customer->Vehicleパス:

modelBuilder.Entity<Vehicle>()
    .HasRequired(v => v.Customer)
    .WithMany()
    .HasForeignKey(v => v.CustomerId)
    .WillCascadeOnDelete(false);

CustomerIdオプションの関係を持つために nullable にすることもできます。その場合、EF はデフォルトでカスケード削除を無効にします。しかし、required を optional リレーションシップに変更することは、Fluent API を避けるためだけに行うつもりはないビジネス ルールの変更を表しています。

CustomerAppointmentところで:複合主キーが必要なのは本当に正しいですか?これは、特定の車両を所有する特定の顧客がサービスの予定を 1 つしか持てないことを意味します。同じ顧客/車両の組み合わせに対して、異なる予約日に多くの予約がありませんか? はいの場合は、主キーの一部ではなく、外部キーとなるandCustomerAppointmentの別のキーを用意する必要があります。CustomerIdVehicleId

于 2013-07-19T22:31:52.710 に答える
0

慣例により、カスケード削除は、実際の外部キーをモデルに導入することによって処理されます。null 非許容の外部キーを使用する場合は、削除が必要になります。無効にするには、null 許容の外部キーを使用します。

外部キーを null 可能にして、クラスを次のように変更します。

[Table("CustomerAppointments")]
public partial class CustomerAppointment
{

    [Key,Column(Order=0)]
    public int? CustomerId { get; set; }

    [Key,Column(Order=1)]
    public int? VehicleId { get; set; }

    public DateTime? AppointmentDate { get; set; }

    public DateTime? AppointmentTime { get; set; }

    public string AvailableDays { get; set; }

    //other fields

    [ForeignKey("CustomerId")]
    public virtual Customer Customer { get; set; }

    [ForeignKey("VehicleId")]
    public virtual Vehicle Vehicle { get; set; }
}

流暢なマッピングも削除することを忘れないでください。

http://msdn.microsoft.com/en-US/data/jj679962から

依存エンティティの外部キーが null 許容でない場合、Code First はリレーションシップにカスケード削除を設定します。依存エンティティの外部キーが null 許容の場合、Code First はリレーションシップにカスケード削除を設定せず、プリンシパルが削除されると、外部キーは null に設定されます。

于 2013-07-19T21:02:16.503 に答える
0

データベースファーストのアプローチを使用してから、ado enity データモデルを使用してモデルを生成する方が良いようです。

于 2013-07-19T21:05:23.250 に答える