web-dev-qa-db-ja.com

Entity Frameworkコードファースト:アノテーションを使用した1対1の外部キー関連付けの設定

外部キーの関連付けを使用して(1対1で)関連付けようとしている2つのエンティティをフォローしています。

_public class StandardRack {
    public int Id {get;set}
    public StandardRelay StandardRelay {get;set} 
}

public class StandardRelay {
    public int Id {get;set} 

    public int StandardRack_Id {get;set;}
    [Required][ForeignKey("StandardRack_Id")]
    public StandardRack StandardRack { get; set; }
}
_

これにより、ModelValidationExceptionがスローされます。このような一見単​​純な1対1の双方向の関係を構成できない理由はありません。

編集:

例外は次のとおりです。

System.Data.Entity.ModelConfiguration.ModelValidationExceptionがキャッチされましたメッセージ=モデルの生成中に1つ以上の検証エラーが検出されました:

System.Data.Edm.EdmAssociationEnd ::多重度は、リレーションシップ 'StandardRelay_StandardRack'のロール 'StandardRelay_StandardRack_Source'では無効です。依存ロールのプロパティはキープロパティではないため、依存ロールの多重度の上限は「*」である必要があります。

Source = EntityFramework StackTrace:at System.Data.Entity.ModelConfiguration.Edm.EdmModelExtensions.ValidateAndSerializeCsdl(EdmModel model、XmlWriter writer)at System.Data.Entity.ModelConfiguration.Edm.EdmModelExtensions.ValidateCsdl(EdmModel model)atSystem.Data.Entity。 .DbModelBuilder.Build(DbProviderManifest providerManifest、DbProviderInfo providerInfo)at System.Data.Entity.DbModelBuilder.Build(DbConnection providerConnection)at System.Data.Entity.Internal.LazyInternalContext.CreateModel(LazyInternalContext internalContext)atSystem.Data.Entity.Internal。 RetryLazy2.GetValue(TInput input) at System.Data.Entity.Internal.LazyInternalContext.InitializeContext() at System.Data.Entity.Internal.InternalContext.Initialize() at System.Data.Entity.Internal.InternalContext.GetEntitySetAndBaseTypeForType(Type entityType) at System.Data.Entity.Internal.Linq.InternalSet 1.Initialize()at System.Data.Entity.Internal.Linq.InternalSet1.GetEnumerator() at System.Data.Entity.Infrastructure.DbQuery 1.System.Collections.Generic.IEnumerable.GetEnumerator()at System.Collections.Generic.List _1..ctor(IEnumerable_ 1コレクション)at System.Linq.Enumerable.ToList [TSource](IEnumerable`1 source)at TestApplication.MainWindow.Window_Loaded(Object sender、RoutedEventArgs e)in D:\ RailwayProjects\RelayAnalysis\TestApplication\MainWindow.xaml.cs :li ne 33 InnerException:

15
Jatin

私は、foreignKeyはStandardRack_idではなくIdであるべきだと思います。また、遅延読み込みを使用できるようにするには、仮想を使用する必要があります。

これは私のために働きます

using System.ComponentModel.DataAnnotations;
using System.Data.Entity;

namespace Racks
{

    public class StandardRack
    {
        public int Id { get; set; }
        public virtual StandardRelay StandardRelay { get; set; }
    }

    public class StandardRelay
    {
        public int Id { get; set; }

        public int StandardRack_Id { get; set; }

        [ForeignKey("Id")]
        [Required]
        public virtual StandardRack StandardRack { get; set; }
    }

    public class Context : DbContext
    {
        static Context()
        {
            Database.SetInitializer<Context>(null);
        }

        public DbSet<StandardRack> StandardRacks { get; set; }
        public DbSet<StandardRelay> StandardRelays { get; set; }

    }

    class Program
    {
        static void Main(string[] args)
        {
            var context = new Context();
            context.Database.Delete();
            context.Database.Create();

            var standardRack = new StandardRack();
            standardRack.StandardRelay = new StandardRelay();

            context.StandardRacks.Add(standardRack);
            context.SaveChanges();
        }
    }
}
8
Arialdo Martini

1対1の外部キーの関連付けは、EntitiyFrameworkではサポートされていません。外部キーを削除し、共有主キーを使用する必要があります(依存関係の主キーは、同時にプリンシパルへの外部キーです)。

public class StandardRack {
    public int Id {get;set}
    public StandardRelay StandardRelay {get;set} 
}

public class StandardRelay {
    public int Id {get;set} 
    public StandardRack StandardRack { get; set; }
}

Fluent APIでのマッピング:

modelBuilder.Entity<StandardRack>()
    .HasOptional(rack => rack.StandardRelay)
    .WithRequired(relay => relay.StandardRack);

(ここでは、StandardRackにオプションのリレーがあることを保証します。)

28
Slauma

流暢なAPIを使用してFKと1対1の関係を指定する方法は次のとおりです。

FKはEnitityで明示的に定義されていませんが、流暢なAPIを使用して定義されていることに注意してください。

public class StandardRack {
    public int Id {get;set}
    public StandardRelay StandardRelay {get;set} 
}

public class StandardRelay {
    public int Id {get;set} 
    public StandardRack StandardRack { get; set; }
}


modelBuilder.Entity<StandardRack>()
            .HasOptional(x => x.StandardRelay)
            .WithOptionalPrincipal(y => y.StandardRack)
            .Map(configurationAction: new Action<ForeignKeyAssociationMappingConfiguration>(x => x.MapKey("StandardRack_Id")));

流暢なAPIは、StandardRelayに列StandardRack_Idを追加します。

メソッド名 WithOptionalPrincipal ()は非常に皮肉なことに注意してください。 WithOptionalDependent のmsdnドキュメントはそれを明確にするものとします。

7
Sudarshan_SMD

StandardRelayでIDの注釈を適合させることをお勧めします。この関連する質問も参照してください。

エンティティフレームワークの1:1関係での関連付けのプリンシパルエンドとはどういう意味ですか

public class Foo
{
    public string FooId{get;set;}
    public Boo Boo{get;set;}
}

public class Boo
{
    [Key, ForeignKey("Foo")]
    public string BooId{get;set;}
    public Foo Foo{get;set;}
}
0
Stefan