我在Entity Framework Core 1.1中遇到此查询的问题:
var leaves = _context.Proposal.OfType<ProposalLeave>()
.Include(l => l.Creator).ThenInclude(e => e.User)
.Include(l=>l.LeaveType) // this include causes the exception
.Include(l => l.ProposalLeaveStatuses).ThenInclude(l => l.ProposalLeaveStatus)
.ToList();
包含LeaveType会引发此错误:
InvalidCastException:无法转换类型为&#39; System.DateTime&#39;的对象 输入&#39; System.Int32&#39;。
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.
}
}
我检查了这些模型数百次,我不知道什么是错的。它的奇怪之处我也有ProposalCustom:与ProposalCustomType竞争的Proposal模型与ProposalLeave:Proposal to ProposalLeaveType相同,它工作正常......
我发现如果我添加该行:
var leaveTypes = _context.ProposalLeaveType.Include(plt => plt.ProposalLeaves).ToList();
在我的查询之前,它甚至可以与.Include(l=>l.LeaveType)
一起使用,没有任何例外...
我在EF github上发现了一些引用InvalidCastException的bug问题,但所有这些问题都在EF Core 1.1中被标记为已修复
@Update 在这里,您可以下载重现该问题的VS2015项目: Project。 设置:
答案 0 :(得分:1)
不幸的是,我所能做的就是确认这个问题是由EF Core错误引起的。
我能够将repro修改为以下内容:
型号:
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();
虽然ProposalCustom
和ProposalLeave
看起来很相似,但第一个查询始终有效,第二个查询不起作用(它在某些情况下有效)你将在下面看到)。
为什么我确定这是一个错误。首先,因为查询和/或模型/配置没有任何问题。看起来它是由几个因素的组合引起的,从TPH开始,派生类属性的数量和类型以及(hmm)派生实体的类名(字母顺序?)。
例如,如果没有LeaveEnd
属性,则第二个查询有效。最有趣的部分(取决于当然的观点)是,如果您将ProposalCustom
课程重命名为ProposalXCustom
,或ProposalLeave
重命名为ProposalALeave
,换句话说,请将问题重新命名为实体类名首先按字母顺序排列(我知道这听起来很疯狂),没有任何数据库结构/映射更改,查询有效!
我建议您将其报告给EF Core存储库。 Substantiation
列和Required
/ Column
属性似乎不会影响该行为。另请注意,第一个查询始终有效,执行顺序无关紧要。