2016-12-25 63 views
3

我有一個問題,1.1這個查詢實體框架的核心:包括原因InvalidCastException的

​​

包括對LeaveType提出這個錯誤:

InvalidCastException: Unable to cast object of type 'System.DateTime' to type 'System.Int32'.

Microsoft.EntityFrameworkCore.ChangeTracking.Internal.SimpleNonNullableDependentKeyValueFactory.TryCreateFromBuffer(Valu fdc eBuffer valueBuffer, out TKey key)

我的模型:

public class Proposal 
{ 
    [Key] 
    public int ProposalId { get; set; } 

    [Required] 
    public DateTime DateCreated { get; set; } 

    [Required] 
    public int CreatorId { get; set; } 

    [ForeignKey("CreatorId")] 
    public Employee Creator { get; set; } 
} 

public class ProposalLeave : Proposal 
{ 
    [Required] 
    public DateTime LeaveStart { get; set; } 

    [Required] 
    public DateTime LeaveEnd { get; set; } 

    [Required] 
    public int ProposalLeaveTypeId { get; set; } 

    [ForeignKey("ProposalLeaveTypeId")] 
    public virtual ProposalLeaveType LeaveType { get; set; } 

    public virtual ICollection<ProposalLeaveStatuses> ProposalLeaveStatuses { get; set; } 
} 

public class ProposalLeaveType 
{ 
    [Key] 
    public int LeaveTypeId { get; set; } 

    [Required, StringLength(255)] 
    public string Name { get; set; } 

    [Required, Column(TypeName = "text")] 
    public string Description { get; set; } 

    public ICollection<ProposalLeave> ProposalLeaves { get; set; } 
} 

我的DbContext的一部分:

public class AppDbContext : IdentityDbContext<User, Role, int> 
{ 

    public DbSet<Proposal> Proposal { get; set; } 
    public DbSet<ProposalLeaveStatus> ProposalLeaveStatus { get; set; } 
    public DbSet<ProposalLeaveStatuses> ProposalLeaveStatuses { get; set; } 
    public DbSet<ProposalLeaveType> ProposalLeaveType { get; set; } 


    public AppDbContext(DbContextOptions<AppDbContext> options) 
     : base(options) 
    { 
    } 

    protected override void OnModelCreating(ModelBuilder modelBuilder) 
    { 
     base.OnModelCreating(modelBuilder); 
     // proposal hierarchy 
     modelBuilder.Entity<Proposal>() 
      .HasDiscriminator<string>("proposal_type") 
      .HasValue<Proposal>("proposal_base") 
      .HasValue<ProposalCustom>("proposal_custom") 
      .HasValue<ProposalLeave>("proposal_leave"); 

     // proposal statuses many to many 
     modelBuilder.Entity<ProposalLeaveStatuses>() 
      .HasOne(pt => pt.Proposal) 
      .WithMany(p => p.ProposalLeaveStatuses) 
      .HasForeignKey(pt => pt.ProposalId) 
      .OnDelete(DeleteBehavior.Restrict); 

     modelBuilder.Entity<ProposalLeaveStatuses>() 
      .HasOne(pt => pt.ProposalLeaveStatus) 
      .WithMany(t => t.ProposalLeaveStatuses) 
      .HasForeignKey(pt => pt.ProposalLeaveStatusId); 

     //Substantially, there are nothing about Proposal Leave Types, cause its relation one-to-many modeled using data annotations. 
    } 
} 

我檢查了這些模型數百次,我不知道什麼是錯的。這很奇怪casuse我也有ProposalCustom:以同樣的方式作爲ProposalLeave與ProposalCustomType contected議案模型:提案ProposalLeaveType並能正常工作......

我發現,如果我再補充一點行:

var leaveTypes = _context.ProposalLeaveType.Include(plt => plt.ProposalLeaves).ToList(); 

我查詢之前,它甚至還帶有.Include(l=>l.LeaveType)沒有任何異常的作品...

我發現EF github上指InvalidCastException的幾個錯誤的問題,但所有的人都被標記爲固定EF核心1.1

@Update 在這裏,您可以下載VS2015項目,重現該問題: Project。 安裝程序:

  1. 安裝.Net Core 1.1。 SDK和Runtime
  2. 創建空數據庫和程序包管理器控制檯appsettings.json更換連接字符串
  3. 運行更新,數據庫
  4. 運行項目。
+0

沒有完整的模型不能重現。如果你註釋掉'.Include(l => l.ProposalLeaveStatuses),那麼會發生什麼。ThenInclude(l => l.ProposalLeaveStatus)'line? –

+0

@IvanStoev它仍然不起作用。只刪除該行:'Include(l => l.LeaveType)'修復了我的問題。這就是爲什麼我跳過我的問題中的ProposalLeaveStatuses和ProposalLeaveStatus模型的定義。稍後我會通過添加DbContext – Kuba

+0

的重要部分來更新我的問題。但是看起來像這樣會影響這個過程,因爲沒有'.ThenInclude(e => e.User)'和第一個註釋中提到的行它不會發生,我的意思是它沒有錯誤。 –

回答

1

不幸的是,我所能做的只是確認一個明顯的事實,即該問題是由EF核心錯誤引起的。

我能夠給攝製減磅以下幾點:

型號:

public class Proposal 
{ 
    [Key] 
    public int ProposalId { get; set; } 

    [Required, Column(TypeName = "text")] 
    public string Substantiation { get; set; } 

    public DateTime DateCreated { get; set; } 
} 

public class ProposalCustom : Proposal 
{ 
    [Required, StringLength(255)] 
    public string Name { get; set; } 

    public int ProposalTypeId { get; set; } 

    [ForeignKey("ProposalTypeId")] 
    public virtual ProposalCustomType ProposalType { get; set; } 
} 

public class ProposalCustomType 
{ 
    [Key] 
    public int ProposalTypeId { get; set; } 

    [Required, StringLength(255)] 
    public string Name { get; set; } 

    [Required, Column(TypeName = "text")] 
    public string Description { get; set; } 

    public ICollection<ProposalCustom> ProposalCustoms { get; set; } 
} 

public class ProposalLeave : Proposal 
{ 
    public DateTime LeaveStart { get; set; } 

    public DateTime LeaveEnd { get; set; } 

    public int ProposalLeaveTypeId { get; set; } 

    [ForeignKey("ProposalLeaveTypeId")] 
    public virtual ProposalLeaveType LeaveType { get; set; } 
} 

public class ProposalLeaveType 
{ 
    [Key] 
    public int LeaveTypeId { get; set; } 

    [Required, StringLength(255)] 
    public string Name { get; set; } 

    [Required, Column(TypeName = "text")] 
    public string Description { get; set; } 

    public ICollection<ProposalLeave> ProposalLeaves { get; set; } 
} 

的DbContext:

public DbSet<Proposal> Proposal { get; set; } 
public DbSet<ProposalCustomType> ProposalCustomType { get; set; } 
public DbSet<ProposalLeaveType> ProposalLeaveType { get; set; } 

配置:

modelBuilder.Entity<Proposal>() 
    .HasDiscriminator<string>("proposal_type") 
    .HasValue<Proposal>("proposal_base") 
    .HasValue<ProposalCustom>("proposal_custom") 
    .HasValue<ProposalLeave>("proposal_leave"); 

數據:

db.Proposal.Add(new ProposalLeave 
{ 
    Substantiation = "S1", 
    DateCreated = DateTime.Today, 
    LeaveStart = DateTime.Today, 
    LeaveEnd = DateTime.Today, 
    LeaveType = new ProposalLeaveType { Name = "PLT1", Description = "PLT1" } 
}); 
db.Proposal.Add(new ProposalCustom 
{ 
    Substantiation = "S2", 
    Name = "PC1", 
    ProposalType = new ProposalCustomType { Name = "PCT1", Description = "PCT1" } 
}); 
db.SaveChanges(); 

查詢:

var proposalCustoms = db.Proposal.OfType<ProposalCustom>() 
    .Include(l => l.ProposalType) 
    .ToList(); 

var proposalLeaves = db.Proposal.OfType<ProposalLeave>() 
    .Include(l => l.LeaveType) 
    .ToList(); 

Althought的ProposalCustomProposalLeave長相相似,第一個查詢總是作品,第二個沒有(它確實根據一些情況,你會看到下面)。

爲什麼我確定它是一個錯誤。首先,因爲查詢和/或模型/配置沒有問題。看起來它是由幾個因素組合而成的,從TPH開始,派生類屬性的數量和類型以及派生實體的類名(字母順序?)。

例如,如果沒有LeaveEnd屬性,則第二個查詢起作用。最有趣的部分(取決於當然的視圖)是,如果您將ProposalCustom類重命名爲ProposalXCustomProposalLeaveProposalALeave,換句話說,首先按照字母順序(我知道這聽起來很瘋狂)製作有問題的實體類名稱,沒有任何數據庫結構/映射的變化,查詢的作品!

我建議你將它報告給EF核心存儲庫。 Substantiation列和Required/Column屬性似乎不會影響行爲。另請注意,第一個查詢總是有效的,執行順序並不重要。

+1

報告的問題[這裏](https://github.com/aspnet/EntityFramework/issues/7312)。感謝幫助。 – Kuba