在迭代器中保存实体时出错

时间:2016-10-20 17:00:05

标签: c# entity-framework

我只是通过迭代类型列表(i.e. Items)的集合将学生添加到数据库中。这里的项目不是强类型。我从其他地方得到这个。所以我需要在将它写入SQL之前从中构造Student对象。它有学生信息。

只要所有字段验证都可以,它对我来说很好。

但是,如果列表中的第一项有验证错误(i.e. Age required field in Student model),我会收到错误,这很好。但对于第二项,我有有效的年龄值,但仍然得到前一项的验证错误。

try
{
     foreach (var item in Items)
    {
        Student student = new Student
        {
            StudentId = item.Id,
            Age = item.Age,
            Description = item.Description
        };

        _context.Student.Add(student);
        _context.SaveChanges();
    }
}    
catch (MyCustomValidationException ex)
{
   //// catch it and log it
}

它是否与第一个仍与上下文相关的项目相关? 我怎么摆脱它?所有我想通过迭代列表中的任何通过验证来保存数据库中的项目。

产品

public class Items
{
  public string Id {get;set;}
  public string Age {get; set;}
  public string Description {get;set;}
}

这就是它的填充方式

items.Add(
new Items 
{
 new Items {Id = 1, Age = null, Description = "ABC"},
 new Items {Id = 1, Age = 12, Description = "ABC"}
}
)

2 个答案:

答案 0 :(得分:2)

首先,您不应该在循环中保存更改,它将导致对数据库的多次插入查询,而不是一次。

其次,我相信您的代码不完整,因为将抛出验证异常,您将不在foreach循环中。但即使您在_context.SaveChanges()周围尝试/捕获它也不会取消您在上下文中仍然存在无效数据并且第二次调用_context.SaveChanges()将尝试为{{Student提交这些更改的事实。 1}}表再次。从您的问题中不清楚,但我认为您已经对学生年龄进行了DB端验证。

答案 1 :(得分:1)

问题是您在Age中有一个必填字段Student,但您为其提供了null值,但无法在数据库中插入。

您应该验证要插入数据库的数据。

foreach (var item in Items)
{
    Student student = new Student
    {
        StudentId = item.Id,
        Age = item.Age,
        Description = item.Description
    };

    if (student.IsValid())
    {
        _context.Student.Add(student);
    } // else do something with invalid data! maybe warn user or log it ...
}
_context.SaveChanges();

IsValid添加到Student

public bool IsValid()
{
    if (string.IsNullOrWhiteSpace(this.Age))
    {
        return false;
    }

    return true;
}

会发生什么事?

通过调用Student向上下文添加无效的_context.Student.Add(student);。每次调用_context.SaveChanges();时,它都会尝试将添加的Student插入数据库。在删除无效的Student之前,您会收到错误消息。调用SaveChanges不是一个好主意,因为每次调用它时它都会访问数据库,这会增加额外的开销。但是,如果您想通过调用SaveChanges()逐个检查有效性并获得例外,则可以尝试此操作。

foreach (var item in Items)
{
    Student student = new Student
    {
        StudentId = item.Id,
        Age = item.Age,
        Description = item.Description
    };

    _context.Student.Add(student);

    try
    {
        _context.SaveChanges();
    }
    catch (MyCustomValidationException ex)
    {
        _context.Student.Remove(student);
    }
}