【问题标题】:Entity Framework validation error for missing field, but it's not missing?缺少字段的实体框架验证错误,但它没有丢失?
【发布时间】:2014-02-05 21:49:18
【问题描述】:

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

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 基于 Expense:

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 已填充,当我使用依赖注入时,检索和添加是在同一上下文中完成的。

非常感谢您的帮助, 约翰

【问题讨论】:

  • 显示调用CreateOrGetExpensePeriod(...)并创建/保存新Expense的代码
  • 完成。感谢观看
  • return _context.UserExpensePeriods.Add(newPeriod) 怎么样?此外,根据您提交的时间,检查_context.UserExpensePeriods.Local_context.UserExpensePeriods 可能是有意义的。
  • 谢谢,但是数据库中已经存在 UserPeriod,所以在函数的第一部分返回。

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


【解决方案1】:

您是否尝试在添加 UserExpense 之前保存并提交 UserExpensePeriods 对象?

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

【讨论】:

  • 嗨 Felipe,当我调试时没有添加新的句点,因为一个已经存在,所以没有什么要提交的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-06-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多