派生类型的键..但事实并非如此
本文关键字:事实 并非如此 类型 派生 | 更新日期: 2024-11-07 15:37:34
我是 EF7 的新手,遇到了一个奇怪的问题。我有这个类:
public class Site
{
public int ID { get; set; }
public string Title { get; set; }
public string HouseNumber { get; set; }
public string StreetName { get; set; }
public string City { get; set; }
public string State { get; set; }
public string Zipcode { get; set; }
public double Latitude { get; set; }
public double Longitude { get; set; }
public DataSource Source { get; set; }
public object Parameters
{
get
{
switch( Source )
{
case DataSource.StealthStats:
return JsonConvert.DeserializeObject<StealthStatsParameters>( JSONParameters );
default:
throw new Exception( "Site::Parameters::get() - Unhandled DataSource " + Source.ToString() );
}
}
set
{
switch( Source )
{
case DataSource.StealthStats:
JSONParameters = JsonConvert.SerializeObject( value );
break;
default:
throw new Exception( "Site::Parameters::set() - Unhandled DataSource " + Source.ToString() );
}
}
}
protected string JSONParameters { get; set; }
public List<Observation> Observations { get; set; }
}
以及上下文的 OnModelCreation() 中的此逻辑:
protected override void OnModelCreating(ModelBuilder builder)
{
base.OnModelCreating(builder);
// Customize the ASP.NET Identity model and override the defaults if needed.
// For example, you can rename the ASP.NET Identity table names and more.
// Add your customizations after calling base.OnModelCreating(builder);
builder.Entity<Site>()
.HasKey( t => t.ID );
builder.Entity<Site>()
.Property( s => s.City )
.IsRequired();
builder.Entity<Site>()
.Property( s => s.HouseNumber )
.IsRequired();
builder.Entity<Site>()
.Property( s => s.Source )
.IsRequired();
builder.Entity<Site>()
.Property( s => s.State )
.IsRequired()
.HasMaxLength( 2 );
builder.Entity<Site>()
.Property( s => s.StreetName )
.IsRequired();
builder.Entity<Site>()
.Property( s => s.Title )
.IsRequired();
builder.Entity<Site>()
.Property( s => s.Zipcode )
.IsRequired()
.HasMaxLength( 10 );
builder.Entity<Observation>()
.HasKey( t => new { t.SiteID, t.TimeStamp } );
builder.Entity<Observation>()
.HasOne( o => o.Site )
.WithMany( s => s.Observations );
}
但是当我运行dnx ef迁移添加时,我收到以下错误消息:
派生类型"SpeedView.Models.Site"不能具有在根类型上声明的键以外的键。
然而,据我所知,网站不是从任何东西派生出来的。
顺便说一句,这是类观察的定义,以防万一重要:
public class Observation
{
public int SiteID { get; set; }
public DateTime TimeStamp { get; set; }
public int MPH { get; set; }
public int VehicleCount { get; set; }
public virtual Site Site { get; set; }
}
顺便说一句,如果有人可以推荐一些指向 EF7 的优秀教程和解释的链接,我将不胜感激。在使用 EF 多年后,我发现它的学习曲线非常陡峭,我在网上找到的东西并没有太大帮助。
我在实体框架的github网站上发布了这个,Smit Patel很快回答了这个问题并解释了正在发生的事情。你可以阅读他在 https://github.com/aspnet/EntityFramework/issues/5151 写的东西。谢谢,帕特尔!
简短的版本是这样的:EF 类中的对象属性会导致创建 EF 迁移的代码在整个扫描中包含对象类型。由于所有类都是从对象派生的,并且对象没有固有的主键,因此所有类都与"只有根类可以定义键"的限制相冲突。
解决方案是不将对象属性映射到基础数据库(这就是我所做的)。
在这样做的过程中,我发现看起来你必须通过将 [NotMapped] 注释应用于属性来表明您的意图。流畅的 API 方法:
builder.Entity<T>().Ignore(t => t.PropertyToIgnore);
不行。