C# 实体框架认为存在一个不存在的列

C# 实体框架认为存在一个不存在的列,c#,entity-framework,asp.net-identity,C#,Entity Framework,Asp.net Identity,我有两张桌子: InboxEvent int Id Visitor Owner [ForeignKey("Owner")] string OwnerId Visitor CausingUser [ForeignKey("CausingUser")] string CausingUserId Visitor string Id OwnerId和CausingUserId都指向Visitor表

我有两张桌子:

InboxEvent
    int Id
    Visitor Owner
    [ForeignKey("Owner")]
    string OwnerId
    Visitor CausingUser
    [ForeignKey("CausingUser")]
    string CausingUserId

Visitor
    string Id
OwnerId和CausingUserId都指向Visitor表,但在Sql Server Entity Framework中,已进入并创建了Inbox事件表,如下所示:

FK OwnerId
FK CausingUserId
FK Visitor_Id
果然,它发明了一个专栏:

NVarChar(128) Visitor_Id
好的。。。古怪的很简单,我将通过手动迁移来消除流浪列:

public partial class KillInboxEventVisitor_Id : DbMigration
{
    public override void Up()
    {
        DropForeignKey("dbo.InboxEvent", "Visitor_Id", "dbo.AspNetUsers");
        DropIndex("dbo.InboxEvent", "IX_Visitor_Id");
        DropColumn("dbo.InboxEvent", "Visitor_Id");
    }
太好了,它不见了!现在。。。每次我试图让EF保存收件箱事件时:

db.InboxEvents.Add(new InboxEvent {...
await db.SaveChangesAsync();
EF爆炸

SqlException:列名“访问者Id”无效。

我该如何告诉潜在的EF模型这个虚构的专栏根本不存在

编辑/更多信息 这是纯实体框架6.x,带有Asp.Net/OWIN标识框架,而不是较新的EF7/Core

我被要求展示全部课程。很乐意,但是,抓住你的屁股,上面缩写它们是有原因的:

public class InboxEvent : IOwnerId
{
    public int Id { get; set; }

    [Index("IX_UserRead", 2)]
    public DateTime CreatedOn { get; set; }

    /// <summary>
    /// The user whose Inbox this event is deposited into.
    /// </summary>
    [ForeignKey("Owner"), Required]
    [MaxLength(128)]
    [Index("IX_UserRead", 0), Index]
    public string OwnerId { get; set; }
    public Visitor Owner { get; set; }

    [Index("IX_EventType_RelatedId1", 0)]
    public InboxEventType EventType { get; set; }

    public Posting.PostCore Post { get; set; }
    [ForeignKey("Post")]
    public int? PostId { get; set; }

    public Posting.PostReply Reply { get; set; }
    [ForeignKey("Reply")]
    public int? ReplyId { get; set; }

    [Index("IX_UserRead", 1)]
    public bool IsRead { get; set; }

    /// <summary>
    /// The user, if any, that caused/triggered this event. For example if A upvotes B, this is A, and B is Visitor.
    /// </summary>
    [ForeignKey("CausingUser")]
    [MaxLength(128)]
    public string CausingUserId { get; set; }
    public Visitor CausingUser { get; set; }


    [Index]
    [Index("IX_EventType_RelatedId1", 1)]
    public int RelatedId1 { get; set; }

    public int RelatedId2 { get; set; }



    public InboxEvent()
    {
        CreatedOn = DateTime.UtcNow;
    }
}

public class Visitor : IdentityUser<string, LoginIdentity, StandardUserRole, IdentityUserClaim>, IVisitor
{
    [MaxLength(22), Column(TypeName = "Char"), Index]
    public string Uid { get; set; }

    [MaxLength(300), Index]
    public string FirstName { get; set; }

    [MaxLength(300), Index]
    public string LastName { get; set; }

    public DateTime CreatedOn { get; set; }
    public DateTime MemberOn { get; set; }
    

    public int Invites { get; set; }
    public int Score { get; set; }

    public bool ShouldReceiveReplyNotifications { get; set; }
    public DateTime LastEmailNotified { get; set; }

    [MaxLength(100), Column(TypeName="VarChar")]
    public string ProfilePic { get; set; }

    public ICollection<UserPhoto> UserPhotos { get; set; }
    public StaticImage StaticImage { get; set; }


    // BioViewModel
    [MaxLength(100)]
    public string Nickname { get; set; }
    [MaxLength(400)]    // TODO Normalize
    public string Disciplines { get; set; }
    [MaxLength(1000)]
    public string MissionStatement { get; set; }
    [MaxLength(100)]
    public string Tagline { get; set; }

    // SkillsViewModel
    [MaxLength(400)]
    public string SkillsKnown { get; set; }
    [MaxLength(400)]
    public string SkillsToLearn { get; set; }

    // PrefsViewModel
    [MaxLength(10)]
    public string PhoneCountryCode { get; set; }
    //[MaxLength(20)]
    //public string PhoneNumber { get; set; }   // Already in base OWIN User model

    public ChatService ChatService { get; set; }
    [MaxLength(100)]
    public string ChatHandle { get; set; }

    public byte PrefIpOpenness { get; set; }
    public byte PrefNonProfit { get; set; }
    public byte PrefMature { get; set; }

    public PrivacyLevel PrivacyNameCountryCity { get; set; }
    public PrivacyLevel PrivacyBio { get; set; }
    public PrivacyLevel PrivacySites { get; set; }
    public PrivacyLevel PrivacyCompanies { get; set; }
    public PrivacyLevel PrivacySkills { get; set; }
    public PrivacyLevel PrivacyContactInfo { get; set; }
    public PrivacyLevel PrivacyCollabPrefs { get; set; }

    public bool WantMonthlyNewsletter { get; set; }
    public bool WantToMentor { get; set; }
    public bool WantToVetProjects { get; set; }
    public bool WantToReviewProjects { get; set; }
    public bool WantToGiveFeedback { get; set; }

    // CommitmentViewModel
    public CommitmentChoice CommitmentChoice { get; set; }
    [MaxLength(1000)]
    public string CommitmentText { get; set; }


    public ICollection<CountryZip> CountryZips { get; set; }
    public ICollection<Org> Orgs { get; set; }
    public ICollection<UserSite> UserSites { get; set; }


    public ICollection<DraftData> Drafts { get; set; }
    public ICollection<Visitor_Team> Teams { get; set; }

    public ICollection<InboxEvent> Inbox { get; set; }
    public ICollection<SubscribedPost> PostSubscriptions { get; set; }



    public async Task<ClaimsIdentity> GenerateUserIdentityAsync(UserManager<Visitor, string> manager)
    {
        // Note the authenticationType must match the one defined in CookieAuthenticationOptions.AuthenticationType
        var userIdentity = await manager.CreateIdentityAsync(this, DefaultAuthenticationTypes.ApplicationCookie);
        // Add custom user claims here
        return userIdentity;
    }


    public Visitor()
    {
        CreatedOn = (DateTime)SqlDateTime.MinValue;
        MemberOn = (DateTime)SqlDateTime.MinValue;
        LastEmailNotified = (DateTime)SqlDateTime.MinValue;
    }
}
public类收件箱事件:IOwnerId
{
公共int Id{get;set;}
[索引(“IX_UserRead”,2)]
public DateTime CreatedOn{get;set;}
/// 
///此事件存放在其收件箱中的用户。
/// 
[外国钥匙(“业主”),必填]
[MaxLength(128)]
[索引(“IX_UserRead”,0),索引]
公共字符串所有者ID{get;set;}
公共访问者所有者{get;set;}
[索引(“IX_EventType_RelatedId1”,0)]
公共InboxventType事件类型{get;set;}
public Posting.PostCore Post{get;set;}
[外侨(“职位”)]
公共int?PostId{get;set;}
public Posting.PostReply回复{get;set;}
[外键(“回复”)]
公共int?ReplyId{get;set;}
[索引(“IX_UserRead”,1)]
公共bool IsRead{get;set;}
/// 
///导致/触发此事件的用户(如果有)。例如,如果A投票给B,则这是A,B是访客。
/// 
[外键(“原因用户”)]
[MaxLength(128)]
公共字符串CausingUserId{get;set;}
公共访问者原因服务{get;set;}
[索引]
[索引(“IX_EventType_RelatedId1”,1)]
公共int-RelatedId1{get;set;}
公共int-RelatedId2{get;set;}
公共收件箱()
{
CreatedOn=DateTime.UtcNow;
}
}
公共类访问者:IdentityUser、IVisitor
{
[MaxLength(22),列(TypeName=“Char”),索引]
公共字符串Uid{get;set;}
[最大长度(300),索引]
公共字符串名{get;set;}
[最大长度(300),索引]
公共字符串LastName{get;set;}
public DateTime CreatedOn{get;set;}
{get;set;}上的公共日期时间成员
公共整数{get;set;}
公共整数分数{get;set;}
公共bool应该接收通知{get;set;}
公共日期时间LastEmailNotified{get;set;}
[MaxLength(100),列(TypeName=“VarChar”)]
公共字符串配置文件pic{get;set;}
公共ICollection用户照片{get;set;}
公共StaticImage StaticImage{get;set;}
//生物视图模型
[MaxLength(100)]
公共字符串昵称{get;set;}
[MaxLength(400)]//TODO规格化
公共字符串规则{get;set;}
[最大长度(1000)]
公共字符串任务语句{get;set;}
[MaxLength(100)]
公共字符串标记行{get;set;}
//SkillsViewModel
[MaxLength(400)]
公共字符串SkillsKnown{get;set;}
[MaxLength(400)]
公共字符串SkillsToLearn{get;set;}
//PrefsViewModel
[MaxLength(10)]
公共字符串PhoneCountryCode{get;set;}
//[MaxLength(20)]
//公共字符串PhoneNumber{get;set;}//已在基本OWIN用户模型中
公共聊天室服务聊天室服务{get;set;}
[MaxLength(100)]
公共字符串ChatHandle{get;set;}
公共字节前缀{get;set;}
公共字节{get;set;}
公共字节预处理{get;set;}
public PrivacyLevel PrivacyNameCountryCity{get;set;}
公共PrivacyLevel PrivacyBio{get;set;}
公共PrivacyLevel PrivacySites{get;set;}
公共私有级别私有公司{get;set;}
公共PrivacyLevel PrivacySkills{get;set;}
公共PrivacyLevel PrivacyContactInfo{get;set;}
公共PrivacyLevel PrivacyCollabPrefs{get;set;}
公共bool WantMonthlyNewsletter{get;set;}
公共bool WantToMentor{get;set;}
公共bool WantToVetProjects{get;set;}
公共bool WantToReviewProjects{get;set;}
公共bool WantToGiveFeedback{get;set;}
//承诺模型
公共承诺选择承诺选择{get;set;}
[最大长度(1000)]
公共字符串CommitmentText{get;set;}
公共ICollection CountryZips{get;set;}
公共ICollection组织{get;set;}
公共ICollection用户站点{get;set;}
公共ICollection草稿{get;set;}
公共ICollection团队{get;set;}
公共ICollection收件箱{get;set;}
公共ICollection PostSubscriptions{get;set;}
公共异步任务GenerateUserIdentityAsync(用户管理器)
{
//注意authenticationType必须与CookieAuthenticationOptions.authenticationType中定义的类型匹配
var userIdentity=wait manager.CreateIdentityAsync(这是DefaultAuthenticationTypes.ApplicationOkie);
//在此处添加自定义用户声明
返回用户身份;
}
公众访客()
{
CreatedOn=(DateTime)SqlDateTime.MinValue;
MemberOn=(DateTime)SqlDateTime.MinValue;
LastEmailNotified=(DateTime)SqlDateTime.MinValue;
}
}
Db确实有一个OnModelsCreating,尽管它不太可能与此相关:

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();

        var entity = modelBuilder.Entity<Visitor>();
        // By default this is nvarchar max? Uh?
        entity.Property(v => v.PhoneNumber).HasMaxLength(20);
    }
模型创建时受保护的覆盖无效(DbModelBuilder modelBuilder)
{
modelBuilder.Conventions.Remove();
var entity=modelBuilder.entity();
//默认情况下,这是nvarchar max?嗯?
Property(v=>v.PhoneNumber).HasMaxLength(20);
}

访客
收件箱
之间有三种关联。您最初展示的两个:

public class InboxEvent : IOwnerId
{
    ...
    [ForeignKey("Owner"), Required]
    public string OwnerId { get; set; }
    public Visitor Owner { get; set; }

    [ForeignKey("CausingUser")]
    public string CausingUserId { get; set; }
    public Visitor CausingUser { get; set; }
    ...
}
以及:

public class Visitor : IdentityUser<string, ...
{
    ...
    public ICollection<InboxEvent> Inbox { get; set; }
    ...
}
public class InboxEvent : IOwnerId
{
    ...
    [ForeignKey("Owner"), Required]
    public string OwnerId { get; set; }

    [InverseProperty("Inbox")]
    public Visitor Owner { get; set; }
    ...
}