EF代码首先验证和更新对象

时间:2015-05-01 12:09:03

标签: entity-framework validation

我正在开发一个N层应用程序,包括UI层(MVC),业务层,域层(用于模型)和DAL用于存储库和EF DbContext。

在更新现有对象的属性时,我对Entity Framework的内部工作方式感到有点困惑,我正在寻找一种在更新数据库中的值之前验证对象的好方法。

我有以下型号:

public class BlogPost
{
    public int BlogPostId { get; set; }

    [Required]
    public String Title { get; set; }

    [Required]
    public String Description { get; set; }

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

    public byte[] Image { get; set; }
}

我在BL的经理中有以下方法:

public BlogPost AddBlogPost(string title, string description, byte[] image = null)
{
    BlogPost blogPost = new BlogPost()
    {
        Title = title,
        Description = description,
        DateTime = DateTime.Now
    };

    Validate(blogPost);
    moduleRepository.CreateBlogPost(blogPost);

    return blogPost;
}

public BlogPost ChangeBlogPost(BlogPost blogPost)
{
    moduleRepository.UpdateBlogPost(blogPost);
    return blogPost;
}

我的DAL中有以下方法:

public BlogPost CreateBlogPost(BlogPost b)
{
    b = context.BlogPosts.Add(b);
    context.SaveChanges();

    return b;
}

public BlogPost UpdateBlogPost(BlogPost b)
{
    context.Entry(b).State = EntityState.Modified;
    context.SaveChanges();

    return b;
}

我现在的问题是:在实际尝试更改数据库中的值之前,检查模型是否有效的好方法是什么?

我在想这样的事情:

public BlogPost ChangeBlogPost(BlogPost blogPost)
{
    // STEP 1: put the updated data in a new object
    BlogPost updatedBlogPost = new BlogPost()
    {
        Title = blogPost.Title,
        Description = blogPost.Description,
        Image = blogPost.Image,
        DateTime = blogPost.DateTime
    };

    // STEP 2: check if the model is valid
    this.Validate(updatedBlogPost);

    // STEP 3: read the existing blog post with that ID and change the properties
    BlogPost b = moduleRepository.ReadBlogPost(blogPost.BlogPostId);

    b.Title = blogPost.Title;
    b.Description = blogPost.Description;
    b.Image = blogPost.Image;
    b.DateTime = blogPost.DateTime;

    moduleRepository.UpdateBlogPost(blogPost);
    return blogPost;
}
编辑:我认为在上述方法中接受原始类型作为参数而不是对象可能会更好。

我觉得简单的更新工作太多了,但我在互联网上找不到任何其他内容。

我可能还值得注意的是,我正在为DbContext使用 singleton ,所以我必须确保Entity Framework在检查这些值是否有效之前不会更改数据库中的值(因为另一个类对上下文的另一个调用可能导致SaveChanges())。

我知道DbContext上的单例是不好的做法,但是在使用多个上下文实例跟踪多个存储库和实体时,我没有看到任何其他选项来避免无数异常。

PS:我还阅读了有关实体框架中的更改跟踪的信息,但我不能完全确定这会影响我正在尝试做什么。

欢迎所有建议和解释。 提前谢谢。

2 个答案:

答案 0 :(得分:0)

您将检查ModelState.IsValid。 MVC中内置了许多可以利用的验证机制。 Built in attributes,例如您在上面引用的[Required] custom validators,使您的业务类实现IValidatableObject,覆盖EF SaveChanges()等等。这篇文章是一个好的开始:https://msdn.microsoft.com/en-us/data/gg193959.aspx

答案 1 :(得分:0)

好的,所以我在用一些虚拟数据做一些研究和测试时回答了我自己的问题。我认为当由于编辑视图而在MVC中更改属性时,EF也会跟踪它并在数据库中对其进行更改。

我发现并不是模型绑定如何工作并且在一些愚弄之后实现模型绑定实际上创建了一个新对象(而不是编辑动态代理的属性)。

我想我现在可以只验证模型,然后只更新数据库中具有相同主键的模型。