我是EF代码第一种方法的新手,
我在这里试图涵盖的任务是包括主记录和子记录,
我的问题陈述无法在主模型中包含子,而master可以包含在子记录中。
ie ..,
可以使用下面的表达式,但是在子记录
中重新创建主表达式var orderItems = _context.OrderItems.Include(o => o.Order).ToList();
如下面的代码抛出异常,
var orders = _context.Orders.Include(o => o.OrderItems).ToList();
例外:
发生了'System.InvalidOperationException'类型的异常 EntityFramework.SqlServer.dll但未在用户代码中处理
其他信息:指定的包含路径无效。该 EntityType'Dsms.Data.EF.OrderModel'未声明导航 名为'OrderItems'的属性。
请告知
//Model classes
public abstract class BaseModel : IDisposable
{
public BaseModel()
{
DrivingSchoolId = Guid.NewGuid();
UserId = Guid.NewGuid();
IsActive = true;
CreatedOn = DateTime.Now;
ModifiedOn = DateTime.Now;
}
[Display(Name = "Driving School")]
public Guid DrivingSchoolId { get; set; }
[Display(Name = "User")]
public Guid UserId { get; set; }
[Display(Name = "Active")]
public bool IsActive { get; set; }
[Display(Name = "Created By")]
public Guid CreatedBy { get; set; }
[Display(Name = "Created On")]
public DateTime CreatedOn { get; set; }
[Display(Name = "Modified By")]
public Guid ModifiedBy { get; set; }
[Display(Name = "Modified On")]
public DateTime ModifiedOn { get; set; }
public void Dispose()
{
}
}
public class OrderModel : BaseModel
{
public OrderModel()
{
OrderId = Guid.NewGuid();
}
[Key]
[Column(Order = 1)]
public Guid OrderId { get; set; }
[Display(Name = "Customer")]
[DataType(DataType.Text)]
[Required(ErrorMessage = "Please select the 'Customer'")]
public Guid CustomerId { get; set; }
[Display(Name = "Bill Number")]
[DataType(DataType.Text)]
//[Required(ErrorMessage = "Please fill the 'Bill Number'")]
[MaxLength(25, ErrorMessage = "Maximum character lenght of 'Bill Number' is 25.")]
public string BillNumber { get; set; }
[Display(Name = "Age Proof")]
[DataType(DataType.Text)]
[Required(ErrorMessage = "Please select the 'Age Proof'")]
public Guid AgeProofGeneralItemId { get; set; }
[Display(Name = "Address Proof")]
[DataType(DataType.Text)]
[Required(ErrorMessage = "Please select the 'Address Proof'")]
public Guid AddressProofGeneralItemId { get; set; }
[Display(Name = "Status")]
[DataType(DataType.Text)]
[Required(ErrorMessage = "Please select the 'Status'")]
public Guid StatusGeneralItemId { get; set; }
[Display(Name = "Training Instructor")]
[DataType(DataType.Text)]
public Guid TrainingInstructorId { get; set; }
[Display(Name = "Training Vehicle")]
[DataType(DataType.Text)]
public Guid TrainingVehiclesGeneralItemId { get; set; }
[Display(Name = "Notes")]
[DataType(DataType.MultilineText)]
[MaxLength(500, ErrorMessage = "Maximum character lenght of 'Notes' is 500.")]
public string Notes { get; set; }
[Display(Name = "Total")]
[DisplayFormat(DataFormatString = "{0:n2}", ApplyFormatInEditMode = true)]
[DataType(DataType.Text)]
[Required(ErrorMessage = "Please fill the 'Total'")]
[RegularExpression(@"\d+(\.\d{1,2})?", ErrorMessage = "Please enter valid 'Total Amount'")]
public decimal Total { get; set; }
[Display(Name = "Discount")]
[DisplayFormat(DataFormatString = "{0:n2}", ApplyFormatInEditMode = true)]
[DataType(DataType.Text)]
[RegularExpression(@"\d+(\.\d{1,2})?", ErrorMessage = "Please enter valid 'Discount Amount'")]
public decimal Discount { get; set; }
//EF Navigation properties starts
public virtual CustomerModel Customer { get; set; }
public virtual DrivingSchoolModel DrivingSchool { get; set; }
public virtual GeneralItemModel AgeProofGeneralItem { get; set; }
public virtual ICollection<GeneralItemModel> AgeProofGeneralItems { get; set; }
public virtual GeneralItemModel AddressProofGeneralItem { get; set; }
public virtual ICollection<GeneralItemModel> AddressProofGeneralItems { get; set; }
public virtual GeneralItemModel StatusGeneralItem { get; set; }
public virtual ICollection<GeneralItemModel> StatusGeneralItems { get; set; }
public virtual InstructorModel TrainingInstructor { get; set; }
public virtual ICollection<InstructorModel> TrainingInstructors { get; set; }
public virtual GeneralItemModel TrainingVehicleGeneralItem { get; set; }
public virtual ICollection<GeneralItemModel> TrainingVehicleGeneralItems { get; set; }
public virtual ICollection<OrderItemModel> OrderItems { get; set; }
public virtual ICollection<OrderTransactionModel> OrderTransactions { get; set; }
}
public class OrderItemModel : BaseModel
{
public OrderItemModel()
{
OrderItemId = Guid.NewGuid();
NoOfTrainingDays = 1;
}
[Key]
[Column(Order = 1)]
public Guid OrderItemId { get; set; }
[Display(Name = "Order")]
[DataType(DataType.Text)]
[Required(ErrorMessage = "Please select the 'Order'")]
public Guid OrderId { get; set; }
[Display(Name = "Service")]
[DataType(DataType.Text)]
[Required(ErrorMessage = "Please select the 'Service'")]
public Guid ServiceId { get; set; }
[Display(Name = "Training Days")]
[DataType(DataType.Text)]
public int NoOfTrainingDays { get; set; }
[Display(Name = "Service Cost")]
[DataType(DataType.Text)]
[Required(ErrorMessage = "Please fill the 'Service Cost'")]
[RegularExpression(@"\d+(\.\d{1,2})?", ErrorMessage = "Please enter valid 'Service Cost'")]
public decimal ServiceCost { get; set; }
[Display(Name = "Total Service Cost")]
[DataType(DataType.Text)]
[Required(ErrorMessage = "Please fill the 'Total Service Cost'")]
[RegularExpression(@"\d+(\.\d{1,2})?", ErrorMessage = "Please enter valid 'Service Cost'")]
public decimal TotalServiceCost { get; set; }
//EF Navigation properties starts
public virtual OrderModel Order { get; set; }
public virtual ServiceModel Service { get; set; }
public virtual ICollection<OrderFormModel> OrderForms { get; set; }
}
public class OrderTransactionModel : BaseModel
{
public OrderTransactionModel()
{
OrderTransactionId = Guid.NewGuid();
}
[Key]
[Column(Order = 1)]
public Guid OrderTransactionId { get; set; }
[Display(Name = "Order")]
[DataType(DataType.Text)]
[Required(ErrorMessage = "Please select the 'Order'")]
public Guid OrderId { get; set; }
[Display(Name = "Payment Type")]
[DisplayFormat(DataFormatString = "{0:n2}", ApplyFormatInEditMode = true)]
[DataType(DataType.Text)]
[Required(ErrorMessage = "Please select the 'Payment Type'")]
public Guid PaymentTypeGeneralItemId { get; set; }
[Display(Name = "Credited Amount")]
[DisplayFormat(DataFormatString = "{0:n2}", ApplyFormatInEditMode = true)]
[DataType(DataType.Text)]
[Required(ErrorMessage = "Please fill the 'Credited Amount'")]
[RegularExpression(@"\d+(\.\d{1,2})?", ErrorMessage = "Please enter valid 'Credited Amount'")]
public decimal Credited { get; set; }
[Display(Name = "Debited Amount")]
[DataType(DataType.Text)]
[Required(ErrorMessage = "Please fill the 'Debited Amount'")]
[RegularExpression(@"\d+(\.\d{1,2})?", ErrorMessage = "Please enter valid 'Debited Amount'")]
public decimal Debited { get; set; }
[Display(Name = "Notes")]
[DataType(DataType.MultilineText)]
[MaxLength(500, ErrorMessage = "Maximum character lenght of 'Notes' is 500.")]
public string Notes { get; set; }
//EF Navigation properties starts
public virtual ICollection<OrderModel> Orders { get; set; }
public virtual GeneralItemModel PaymentTypeGeneralItem { get; set; }
public virtual ICollection<GeneralItemModel> PaymentTypeGeneralItems { get; set; }
}
//EF's DB Config's
public class OrderConfiguration : EntityTypeConfiguration<OrderModel>
{
public OrderConfiguration()
{
this.ToTable("Orders", Constants.Database.DEFAULT_DB_SCHEMA);
this.HasKey(o => o.OrderId);
this.HasRequired(o => o.Customer).WithMany().HasForeignKey(o => o.CustomerId).WillCascadeOnDelete(false);
this.HasRequired(o => o.DrivingSchool).WithMany().HasForeignKey(o => o.DrivingSchoolId).WillCascadeOnDelete(false);
this.HasRequired(o => o.AgeProofGeneralItem).WithMany().HasForeignKey(o => o.AgeProofGeneralItemId).WillCascadeOnDelete(false);
this.HasRequired(o => o.AddressProofGeneralItem).WithMany().HasForeignKey(o => o.AddressProofGeneralItemId).WillCascadeOnDelete(false);
this.HasRequired(o => o.StatusGeneralItem).WithMany().HasForeignKey(o => o.StatusGeneralItemId).WillCascadeOnDelete(false);
this.HasRequired(o => o.TrainingInstructor).WithMany().HasForeignKey(o => o.TrainingInstructorId).WillCascadeOnDelete(false);
this.HasRequired(o => o.TrainingVehicleGeneralItem).WithMany().HasForeignKey(o => o.TrainingVehiclesGeneralItemId).WillCascadeOnDelete(false);
this.Property(o => o.CustomerId).IsRequired().HasColumnOrder(2);
this.Property(o => o.DrivingSchoolId).IsRequired().HasColumnOrder(3);
this.Property(o => o.BillNumber).HasMaxLength(25).IsRequired().HasColumnOrder(4);
this.Property(o => o.AgeProofGeneralItemId).IsRequired().HasColumnOrder(5);
this.Property(o => o.AddressProofGeneralItemId).IsRequired().HasColumnOrder(6);
this.Property(o => o.StatusGeneralItemId).IsRequired().HasColumnOrder(7);
this.Property(o => o.TrainingInstructorId).IsOptional().HasColumnOrder(8);
this.Property(o => o.TrainingVehiclesGeneralItemId).IsOptional().HasColumnOrder(9);
this.Property(o => o.Total).IsRequired().HasColumnOrder(10);
this.Property(o => o.Discount).IsOptional().HasColumnOrder(11);
this.Property(o => o.Notes).HasMaxLength(500).IsOptional().HasColumnOrder(12);
this.Property(o => o.IsActive).IsRequired().HasColumnOrder(13);
this.Property(o => o.CreatedBy).IsRequired().HasColumnOrder(14);
this.Property(o => o.CreatedOn).IsRequired().HasColumnOrder(15);
this.Property(o => o.ModifiedBy).IsOptional().HasColumnOrder(16);
this.Property(o => o.ModifiedOn).IsOptional().HasColumnOrder(17);
this.Ignore(o => o.UserId);
this.Ignore(o => o.AgeProofGeneralItems);
this.Ignore(o => o.AddressProofGeneralItems);
this.Ignore(o => o.StatusGeneralItems);
this.Ignore(o => o.TrainingInstructors);
this.Ignore(o => o.TrainingVehicleGeneralItems);
this.Ignore(o => o.OrderItems);
this.Ignore(o => o.OrderTransactions);
}
}
public class OrderItemConfiguration : EntityTypeConfiguration<OrderItemModel>
{
public OrderItemConfiguration()
{
this.ToTable("OrderItems", Constants.Database.DEFAULT_DB_SCHEMA);
this.HasKey(oi => oi.OrderItemId);
this.HasRequired(oi => oi.Order).WithMany().HasForeignKey(oi => oi.OrderId).WillCascadeOnDelete(false);
this.HasRequired(oi => oi.Service).WithMany().HasForeignKey(oi => oi.ServiceId).WillCascadeOnDelete(false);
this.Property(oi => oi.OrderId).IsRequired().HasColumnOrder(2);
this.Property(oi => oi.ServiceId).IsRequired().HasColumnOrder(3);
this.Property(oi => oi.NoOfTrainingDays).IsOptional().HasColumnOrder(4);
this.Property(oi => oi.ServiceCost).IsRequired().HasColumnOrder(5);
this.Property(oi => oi.TotalServiceCost).IsRequired().HasColumnOrder(6);
this.Property(oi => oi.IsActive).IsRequired().HasColumnOrder(7);
this.Property(oi => oi.CreatedBy).IsRequired().HasColumnOrder(8);
this.Property(oi => oi.CreatedOn).IsRequired().HasColumnOrder(9);
this.Property(oi => oi.ModifiedBy).IsOptional().HasColumnOrder(10);
this.Property(oi => oi.ModifiedOn).IsOptional().HasColumnOrder(11);
this.Ignore(oi => oi.DrivingSchoolId);
this.Ignore(oi => oi.UserId);
this.Ignore(oi => oi.OrderForms);
}
}
public class OrderTransactionConfiguration : EntityTypeConfiguration<OrderTransactionModel>
{
public OrderTransactionConfiguration()
{
this.ToTable("OrderTransactions",Constants.Database.DEFAULT_DB_SCHEMA);
this.HasKey(ot => ot.OrderTransactionId);
this.HasRequired(ot => ot.Orders).WithMany().HasForeignKey(ot => ot.OrderId).WillCascadeOnDelete(false);
this.HasRequired(ot => ot.PaymentTypeGeneralItem).WithMany().HasForeignKey(ot => ot.PaymentTypeGeneralItemId).WillCascadeOnDelete(false);
this.Property(ot => ot.OrderId).IsRequired().HasColumnOrder(2);
this.Property(ot => ot.PaymentTypeGeneralItemId).IsRequired().HasColumnOrder(3);
this.Property(ot => ot.Credited).IsOptional().HasColumnOrder(4);
this.Property(ot => ot.Debited).IsOptional().HasColumnOrder(5);
this.Property(ot => ot.Notes).HasMaxLength(500).IsOptional().HasColumnOrder(6);
this.Property(ot=> ot.IsActive).IsRequired().HasColumnOrder(7);
this.Property(ot=> ot.CreatedBy).IsRequired().HasColumnOrder(8);
this.Property(ot=> ot.CreatedOn).IsRequired().HasColumnOrder(9);
this.Property(ot=> ot.ModifiedBy).IsOptional().HasColumnOrder(10);
this.Property(ot=> ot.ModifiedOn).IsOptional().HasColumnOrder(11);
this.Ignore(ot => ot.DrivingSchoolId);
this.Ignore(ot => ot.UserId);
this.Ignore(ot => ot.PaymentTypeGeneralItems);
}
}
答案 0 :(得分:2)
您遇到的问题是由流畅的配置引起的:
OrderConfigiration
this.Ignore(o => o.OrderItems);
使用此行,您告诉EF忽略OrderItems
属性,换句话说,OrderItems
不导航属性 - 正是Include
错误信息说。
OrderItemConfiguration
this.HasRequired(oi => oi.Order).WithMany().HasForeignKey(oi => oi.OrderId).WillCascadeOnDelete(false);
在这里,您告诉EF 单向与许多侧的仅引用导航属性,并且< em>一个方。
通常,始终只在一个地方配置关系,并确保它反映导航/ FK属性的确切存在/不存在。
要解决此问题,请删除第一行(使用Ignore
)并按如下所示修改第二行:
this.HasRequired(oi => oi.Order)
.WithMany(o => o.OrderItems) // <- here
.HasForeignKey(oi => oi.OrderId)
.WillCascadeOnDelete(false);