派生类型的键..但事实并非如此

本文关键字:事实 并非如此 类型 派生 | 更新日期: 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);

不行。