缺少字段的实体框架验证错误,但它没有丢失?

时间:2014-02-05 21:49:19

标签: c# .net entity-framework entity-framework-6

我有一个费用实体,它与费用期有必要的关系。它的定义如下:

public class UserExpense
{
    [Key]
    public virtual int ExpenseId { get; set; }

    [Required]
    public virtual DateTime DateIncurred { get; set; }

    [Required]
    public virtual DateTime DateAdded { get; set; }

    [Required]
    public virtual DateTime LastModified { get; set; }

    [Required]
    public virtual ExpenseType ExpenseType { get; set; }

    [Required]
    public virtual string Title { get; set; }

    public virtual string Comment { get; set; }

    public virtual decimal TotalAmount { get; set; }

    [Required]
    public virtual UserExpensePeriod ExpensePeriod { get; set; }

    public virtual Project Project { get; set; }

    public virtual IList<ExpenseReceipt> Receipts { get; set; }

    public virtual ObjectStatus Status { get; set; }
}

当我添加新费用时,我有一种方法可以查找费用适用的现有期间,或者创建一个新期间并将其返回。这是代码:

public UserExpensePeriod CreateOrGetExpensePeriod(int userId, DateTime date)
{
    var existing = _context.UserExpensePeriods.FirstOrDefault(e => e.User.UserId == userId && e.StartDate <= date && e.EndDate >= date);
    if (existing != null)
    {
        return existing;
    }

    var user = _context.Users.FirstOrDefault(u => u.UserId == userId);
    var newPeriod = new UserExpensePeriod()
    {
        StartDate = new DateTime(date.Year, date.Month, 1),
        EndDate = new DateTime(date.Year, date.Month, DateTime.DaysInMonth(date.Year, date.Month)),
        Status = ExpenseStatus.Draft,
        Name = date.ToString("MMMM") + " " + date.Year.ToString(),
        User = user
    };

    _context.UserExpensePeriods.Add(newPeriod);
    return newPeriod;
}

这是创建新费用的方法。映射服务是Automapper的抽象。 MileageExpense基于费用:

public void CreateMileageExpense(MileageExpenseViewModel model, int createdByUserId, string ipAddress, string userAgent)
{
    var user = _unitOfWork.UserRepository.GetById(createdByUserId);

    var expense = _mappingService.Map<MileageExpenseViewModel, MileageExpense>(model);
    expense.DateAdded = DateTime.UtcNow;
    expense.LastModified = expense.DateAdded;
    expense.ExpensePeriod = _unitOfWork.ExpenseRepository.CreateOrGetExpensePeriod(createdByUserId, expense.DateAdded);
    expense.DistanceMeasurement = user.Company.Jurisdiction.DistanceMeasurement;
    expense.EngineSize = _unitOfWork.CompanyRepository.GetEngineSize(model.EngineSizeId);
    expense.MileageRatesApplied = CalculateMileageAmountByEngineSize(expense);

    if (model.SelectedProjectId.HasValue)
    {
        expense.Project = _unitOfWork.ProjectRepository.GetById(model.SelectedProjectId.Value);
    }

    _unitOfWork.ExpenseRepository.AddMileageExpense(expense);
    _unitOfWork.SaveChanges();           

}

当我调试时,我可以看到此方法返回正确的句点(在这种情况下,它不是作为已存在的那个创建的)。

然后我将新费用添加到数据上下文DbSet。当我保存更改时,我收到一个错误,告诉我ExpensePeriod是必填字段。

有谁知道为什么会这样? Pk被填充,因为我正在使用依赖注入,所以检索和添加都在相同的上下文中完成。

非常感谢你的帮助, 约翰

1 个答案:

答案 0 :(得分:0)

您是否尝试在添加用户费用之前保存并提交用户费用期间对象?

_context.SaveChanges(true);
_context.AcceptAllChanges();