我正在尝试使用外键关联跟随两个实体(一对一)。
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。任何想法为何无法配置这种看似简单的一对一双向关系。
修改
以下是例外:
捕获了System.Data.Entity.ModelConfiguration.ModelValidationException 消息=在模型生成期间检测到一个或多个验证错误:
System.Data.Edm.EdmAssociationEnd :: Multiplicity在Role' StandardRelay_StandardRack_Source'中无效。在关系' StandardRelay_StandardRack'。由于Dependent Role属性不是关键属性,因此Dependent Role的多重性的上限必须为�*�。
源=的EntityFramework 堆栈跟踪: 在System.Data.Entity.ModelConfiguration.Edm.EdmModelExtensions.ValidateAndSerializeCsdl(EdmModel model,XmlWriter writer) 在System.Data.Entity.ModelConfiguration.Edm.EdmModelExtensions.ValidateCsdl(EdmModel模型) 在System.Data.Entity.DbModelBuilder.Build(DbProviderManifest providerManifest,DbProviderInfo providerInfo) 在System.Data.Entity.DbModelBuilder.Build(DbConnection providerConnection) 在System.Data.Entity.Internal.LazyInternalContext.CreateModel(LazyInternalContext internalContext) 在System.Data.Entity.Internal.RetryLazy
2.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() 在System.Collections.Generic.List1..ctor(IEnumerable
1个集合) 在System.Linq.Enumerable.ToList [TSource](IEnumerable`1 source) 在T:\ RailwayProjects \ RelayAnalysis \ TestApplication \ MainWindow.xaml.cs中的TestApplication.MainWindow.Window_Loaded(Object sender,RoutedEventArgs e):第33行 InnerException:
答案 0 :(得分:28)
Entitiy Framework不支持一对一外键关联。您必须删除外键并使用共享主键(从属的主键是它同时对主体的外键):
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
有一个可选的接力。)
答案 1 :(得分:8)
我认为foreignKey应该是Id,而不是StandardRack_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();
}
}
}
答案 2 :(得分:5)
以下是如何使用流畅的api指定与FK的一对一关系。
请注意,在Enitity中没有明确定义FK,但是使用流畅的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会在StandardRack_Id
中添加列StandardRelay
。
请注意,方法名称WithOptionalPrincipal()非常具有讽刺意味。 WithOptionalDependent的msdn文档应明确说明。
答案 3 :(得分:0)
您可能希望在StandardRelay中调整ID的注释。另请参阅此相关问题:
What does principal end of an association means in 1:1 relationship in Entity framework
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;}
}