使用Include()方法EF Code First Approach

时间:2017-04-30 08:06:20

标签: entity-framework ef-code-first entity-framework-core

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

1 个答案:

答案 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);