派生类型的关键......但它不是

时间:2016-04-22 15:11:26

标签: c# entity-framework

我是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; }
}

和上下文中的逻辑OnModelCreating():

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合作多年后,我发现它的学习曲线非常陡峭,我在网上发现的东西并不是非常有用。

1 个答案:

答案 0 :(得分:3)

我在实体框架的github网站上发布了这个,并且Smit Patel很快回答了这个问题并解释了发生了什么。你可以阅读他在https://github.com/aspnet/EntityFramework/issues/5151写的内容。 Thanx,Patel!

简短版本是这样的:EF类中的对象属性导致创建EF迁移的代码在整个扫描中包含对象类型。由于所有类都是来自对象,而对象没有固有的主键,所有类都与“只有根类可以定义键”的限制相冲突。

解决方案是不将对象属性映射到底层数据库(这就是我所做的)。

通过这样做,我发现你必须通过将[NotMapped]注释应用于属性来表示你的意图。流畅的API方法:

builder.Entity<T>().Ignore(t => t.PropertyToIgnore);

不起作用。