And*_*lia 5 c# validation entity-framework
我有一个在 C# 中使用实体框架的简单场景。我有一个实体帖子:
public class Post
{
public int Id { get; set; }
public string Name { get; set; }
public string Description { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
在我的 PostManager 我有这些方法:
public int AddPost(string name, string description)
{
var post = new Post() { Name = name, Description = description };
using (var db = new DbContext())
{
var res = db.Posts.Add(post);
res.Validate();
db.SaveChanges();
return res.Id;
}
}
public void UpdatePost(int postId, string newName, string newDescription)
{
using (var db = new DbContext())
{
var data = (from post in db.Posts.AsEnumerable()
where post.Id == postId
select post).FirstOrDefault();
data.Name = newName;
data.Description = newDescription;
data.Validate();
db.SaveChanges();
}
}
Run Code Online (Sandbox Code Playgroud)
方法 validate() 指的是类:
public static class Validator
{
public static void Validate(this Post post)
{
if ( // some control)
throw new someException();
}
Run Code Online (Sandbox Code Playgroud)
我在 savechanges() 之前但在将对象添加到上下文之后调用了 validate 方法。在这个简单的场景中验证数据的最佳实践是什么?最好验证参数?如果在将对象添加到上下文后验证方法抛出异常,对象 post 会发生什么?
更新:
我必须根据数据验证错误抛出一组自定义异常。
我强烈建议您(如果可能的话)修改您的实体,以便设置器是私有的(不用担心,EF 仍然可以在代理创建时设置它们),将默认构造函数标记为受保护(EF 仍然可以进行延迟加载/代理创建),并让唯一可用的公共构造函数检查参数。
这样做有几个好处:
int
?” 如果一开始就不可能做到的话。我知道现在很流行将所有“模型”放入带有 getter 和 setter 的愚蠢属性包中,并且只有一个默认构造函数,因为(坏的)ORM 迫使我们这样做,但情况已不再是这样,并且有这个海事组织有很多问题。
代码示例:
public class Post
{
protected Post() // this constructor is only for EF proxy creation
{
}
public Post(string name, string description)
{
if (/* validation check, inline or delegate */)
throw new ArgumentException();
Name = name;
Description = description;
}
public int Id { get; private set; }
public string Name { get; private set; }
public string Description { get; private set; }
}
Run Code Online (Sandbox Code Playgroud)
那么你的PostManager
代码就变得微不足道了:
using (var db = new DbContext())
{
var post = new Post(name, description); // possibly try-catch here
db.Posts.Add(post);
db.SaveChanges();
return post.Id;
}
Run Code Online (Sandbox Code Playgroud)
如果创建/验证逻辑极其复杂,那么这种模式非常适合重构为负责创建的工厂。
我还要指出的是,如果您非常关心这类事情,那么将数据封装在暴露最小状态更改 API 的实体中会导致类更容易单独测试几个数量级。
我总是使用两个验证:
请记住,您可以编写自定义数据注释属性,该属性可以验证您需要的任何内容。
归档时间: |
|
查看次数: |
15669 次 |
最近记录: |