Ошибка проверки для одного или нескольких объектов — SaveChanges EF4

#c# #asp.net-mvc-3 #entity-framework-4

#c# #asp.net-mvc-3 #entity-framework-4

Вопрос:

Я пытаюсь написать метод, который генерирует несколько счетов. Это для колледжа, где клиенты зачисляются с преподавателями в классе под названием Зачисления. С помощью этого метода я пытаюсь накопить ежемесячную плату клиентов tutors, умноженную на процент их комиссионных, поскольку преподаватели получают определенную комиссию за уроки, которые они дают. Вот мой код для этого:

 public ActionResult CreateBulkCommissions()
{
    var month = DateTime.Now.ToString("MMMM");

    var enrolments = db.Enrollments.ToList();

    var newCommissions = from enrolment in enrolments
                         select new TutorCommission()
                         {
                             CommissionAmount = enrolment.MonthlyFee,
                             CommissionMonth = month,  // string constant 
                             CommissionStatus = "Unpaid",
                             Tutor = new Tutor { TutorNoID = enrolment.Tutor.TutorNoID, TutorCommissionPercentage = enrolment.Tutor.TutorCommissionPercentage }
                         };
    foreach (var newCommission in newCommissions)
    {
        List<TutorCommission> TutorComs = newCommissions.GroupBy(g => g.Tutor).Select(s => new TutorCommission
        {
            CommissionAmount = s.Sum(u => u.CommissionAmount) * s.Key.TutorCommissionPercentage,
            TutorNoID = s.Key.TutorNoID

        }).ToList();

        db.TutorCommission.Add(newCommission);
        db.SaveChanges();
    }

    return RedirectToAction("Index");
}
  

При SaveChanges я получаю сообщение об ошибке проверки для одного или нескольких объектов. Когда я просматриваю значения newCommissions во время отладки, я замечаю, что в TutorCommission, CommissionID и TutorNoID равны 0, что может быть проблемой? Как мне решить эту проблему? Вот скриншот этого: Ошибка отладки

Это соответствующие классы:

 public class Enrollment
{
    [Key]
    [Display(Name = "Enrollment ID Number")]
    public long EnrollmentIDNumber { get; set; }
    [Display(Name = "Client ID Number")]
    public long ClientNumberID { get; set; }
    [Display(Name = "Tutor ID Number")]
    public long TutorNoID { get; set; }
    [Display(Name = "Course Name")]
    public string CourseName { get; set; }
    [Display(Name = "Lesson Time")]
    public string LessonTime { get; set; }
    [Display(Name = "Lesson Day")]
    public string LessonDay { get; set; }
    [Display(Name = "Lesson Location")]
    public string LessonLocation { get; set; }
    [Display(Name = "Lesson Type")]
    public string LessonType { get; set; }
    [Display(Name = "Lesson Level")]
    public string LessonLevel { get; set; }
    [Display(Name = "Monthly Fee")]
    public long MonthlyFee { get; set; }

    public virtual Client Client { get; set; }
    public virtual Tutor Tutor { get; set; }

}

public class TutorCommission
{
    [Key]
    [Display(Name = "Commission ID")]
    public long CommissionID { get; set; }
    [Display(Name = "Commission Month")]
    public string CommissionMonth {get; set;}
    [Display(Name = "Commission Amount")]
    public double CommissionAmount { get; set; }
    [Display(Name = "Commission Status")]
    public string CommissionStatus { get; set; }
    [Display(Name = "Tutor ID Number")]
    public long TutorNoID { get; set; }

    public virtual Tutor Tutor { get; set; }
    public virtual ICollection<CommissionPayments> CommissionPayments { get; set; }

}

public class Tutor
{
    [Key]
    [Display(Name = "Tutor ID Number")]
    public long TutorNoID { get; set; }
    [Required]
    [StringLength(50, ErrorMessage="First name must be less than 50 characters")]
    [Display(Name = "First Name")]
    public string TutorFirstName { get; set; }
    [StringLength(50, ErrorMessage = "Last name must be less than 50 characters")]
    [Display(Name = "Last Name")]
    public string TutorLastName { get; set; }
    [DisplayFormat(DataFormatString = "{0:d}", ApplyFormatInEditMode = true)]
    [Display(Name = "Birth Date")]
    public DateTime? TutorBirthDate { get; set; }
    [Display(Name = "Cellphone Number")]
    public string TutorCellphoneNumber { get; set; }
    [Display(Name = "Home Number")]
    public string TutorHomeNumber { get; set; }
    [RegularExpression("^[a-z0-9_\ -] (\.[a-z0-9_\ -] )*@[a-z0-9-] (\.[a-z0-9-] )*\.([a-z]{2,4})$", ErrorMessage = "Not a valid email address")]
    [Display(Name = "Email Address")]
    public string TutorEmailAddress { get; set; }
    [Display(Name = "Street Address")]
    public string TutorStreetAddress { get; set; }
    [Display(Name = "Suburb")]
    public string TutorSuburb { get; set; }
    [Display(Name = "City")]
    public string TutorCity { get; set; }
    [Display(Name = "Postal Code")]
    public string TutorPostalCode { get; set; }
    [Display(Name="Full Name")]
    public string FullName
    {
        get
        {
            return TutorFirstName   " "   TutorLastName;
        }
    }
    [Display(Name="Commission Percentage")]
    [Required]
    public double TutorCommissionPercentage { get; set; }

    public virtual ICollection<Enrollment> Enrollments { get; set; }
    public virtual ICollection<TutorCommission> TutorCommissions { get; set; }

}
  

В EntityValidationErrors:

Count = 1
{System.Data.Entity.Проверка.DbEntityValidationResult}

Спасибо, Эми

Комментарии:

1. Вы используете EDMX или Code-first?

2. Объекты @CodingGorilla EDMX не являются чистыми, как это. Это определенно CodeFirst

3. @HasanKhan Это то, что я понял; но я просто хотел убедиться.

4. @Amy Можете ли вы опубликовать то, что находится внутри исключения проверки в EntityValidationErrors?

5. @Amy Похоже, что ваши ключи не заполняются; вы ожидаете, что это будут идентификационные ключи, которые создаются на сервере?

Ответ №1:

Попробуйте изменить:

 ...
from enrolment in enrolments
                     select new TutorCommission()
                     {
                         CommissionAmount = enrolment.MonthlyFee,
                         CommissionMonth = month,  // string constant 
                         CommissionStatus = "Unpaid",
                         Tutor = new Tutor { TutorNoID = enrolment.Tutor.TutorNoID, TutorCommissionPercentage = enrolment.Tutor.TutorCommissionPercentage }
                     };
  

Для:

 from enrolment in enrolments
                     select new TutorCommission()
                     {
                         CommissionAmount = enrolment.MonthlyFee,
                         CommissionMonth = month,  // string constant 
                         CommissionStatus = "Unpaid",
                         Tutor = enrolment.Tutor
                     };
  

Потому что, когда вы пытаетесь добавить новые newCommissions в базу данных, EF пытается вставить новых преподавателей вместо создания ассоциации.

Комментарии:

1. Спасибо, ошибки проверки теперь исчезли. Но проблема в том, что он создает новые комиссионные квитанции за регистрацию, где я хочу суммировать зачисления в одну комиссионную квитанцию (таким образом, одна комиссионная квитанция на каждого преподавателя за месяц). И это просто добавление полной суммы ежемесячной платы вместо единицы, умноженной на процент комиссии. Можете ли вы понять, почему это может быть?