5

私はこれを機能させるために一日中試しました。EFのFluentAPIについて多くのことを学びました(たとえば、これは優れた記事です)が、成功しませんでした。

私には3つのエンティティがあります:

public class Address
{
   [Key]
   public virtual int AddressId { get; set; }
   public virtual string AddressString { get; set; }
}
public class User
{
   [Key]
   public virtual int UserId { get; set; }
   public virtual ICollection<Address> Addresses { get; set; }
}
public class House
{
   [Key]
   public virtual int HouseId { get; set; }
   public virtual Address Address { get; set; }
}

とのすべての組み合わせを試しHasMany, HasOptional, WithOptional, WithOptionalDependentてみWithOptionalPrincipialましたUserHouse

protected override void OnModelCreating(DbModelBuilder modelBuilder)

私はそれを機能させることができません。私が欲しいものは明確にすべきだと思います。ユーザーは複数のアドレスを持っている可能性があります(最初は少なくとも1つを強制したいのですが、ユーザーがオプションのアドレスを持っていれば幸いです...)ハウスにはアドレスが1つだけあります-これは必要。家の住所がカスケード削除されるといいですね。

4

2 に答える 2

4

私は次のことがあなたのために働くはずだと信じています

public class Address
{
    public int AddressId { get; set; }
    public string AddressString { get; set; }
}

public class User
{
    public int UserId { get; set; }
    public virtual ICollection<Address> Addresses { get; set; }
}

public class House
{
    public int HouseId { get; set; }
    public virtual Address Address { get; set; }
}

public class TestContext : DbContext
{
    public DbSet<Address> Addresses { get; set; }
    public DbSet<User> Users { get; set; }
    public DbSet<House> Houses { get; set; }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Entity<User>().HasMany(u => u.Addresses).WithMany();
        modelBuilder.Entity<House>().HasRequired(h => h.Address).WithOptional().Map(m => m.MapKey("AddressId"));
    }
}

多くの場合、外部キーフィールドを自分で指定する方がよいことに注意してください。これにより、後で作業が大幅に楽になります。これを行う場合は、Houseを次のように書き直すことを選択できます。

public class House
{
    public int HouseId { get; set; }
    public int AddressId { get; set; }
    public virtual Address Address { get; set; }
}

コンベンションはAddressIdとAddressをリンクします。HouseとAddressの間に1対1のマッピングがある場合は、それらを主キーにリンクすることもできます。

public class House
{
    [ForeignKey("Address")]              
    public int HouseId { get; set; }
    public virtual Address Address { get; set; }
}

少なくとも1つのアドレスを適用したいとおっしゃいましたが、これは1対多の関係では不可能です。これを実行できるのは、ユーザーのアドレスが1つだけの場合のみです。その時点で、Userクラスに必要なAddressIdプロパティを追加できます。

もう1つのコメント-コード内ですべてを仮想化しました。ナビゲーションプロパティを仮想化するだけで済みます。

于 2012-11-07T08:44:47.183 に答える
1

このようなものはどうですか?

を強制AddressするHouse

modelBuilder.Entity<House>().HasRequired(d => d.Address);

Userとの間で1対多の関係を作成するにはAddress

modelBuilder.Entity<User>().HasMany(u => u.Addresses).WithMany().Map(x =>
{
    x.MapLeftKey("UserId");
    x.MapRightKey("AddressId");
    x.ToTable("UserAddress");
});

UserAddressこれが行うべきことは、をにマップするというテーブルを作成することUserですAddress

または、自分用のPOCOを作成してUserAddress、問題のテーブルを変更することもできます。

public class UserAddress
{
    [Key]
    public int UserAddressId { get; set; }
    public User User { get; set; }
    public Address Address { get; set; }
}

public User
{
    ...
    public virtual ICollection<UserAddress> UserAddresses { get; set; }
    ...
}

public Address
{
    ...
    public virtual ICollection<UserAddress> UserAddresses { get; set; }
    ...
}

User次に、とが両方とも必要であることを確認するために、次のものが必要になりAddressます。

modelBuilder.Entity<UserAddress>().HasRequired(u => u.Address);
modelBuilder.Entity<UserAddress>().HasRequired(u => u.User);
于 2012-11-06T20:14:16.157 に答える