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

Entity framework EF代码首先验证和更新对象,entity-framework,validation,Entity Framework,Validation,我正在开发一个N层应用程序,它由一个UI层(MVC)、一个业务层、一个域层(用于模型)和一个用于存储库和EF DbContext的DAL组成 在更新现有对象的属性时,我对Entity Framework的内部工作方式有点困惑,我正在寻找一种在更新数据库中的对象值之前验证对象的好方法 我有以下型号: public class BlogPost { public int BlogPostId { get; set; } [Required] public String Ti

我正在开发一个N层应用程序,它由一个UI层(MVC)、一个业务层、一个域层(用于模型)和一个用于存储库和EF DbContext的DAL组成

在更新现有对象的属性时,我对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使用单例,因此我必须确保Entity Framework在检查这些值是否有效之前不会更改数据库中的值(因为另一个类对上下文的另一次调用可能会导致SaveChanges())

我知道DbContext上的单例是一种不好的做法,但在处理由多个上下文实例跟踪的多个存储库和实体时,我没有看到其他选项可以避免无数的异常

PS:我也读过实体框架中的变更跟踪,但我不能100%确定这将如何影响我的工作

欢迎提出建议和解释。
提前感谢。

您可以检查ModelState.IsValid。MVC中内置了许多验证机制,您可以利用这些机制。例如上面引用的[Required],使您的业务类实现IValidatableObject,覆盖EF SaveChanges(),仅举几个例子。这篇文章是一个很好的开始:

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

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


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

谢谢Steve的回答!这给了我更多的洞察力:)