首页 新闻 搜索 专区 学院

EF , 有没可能只验证指定属性

1
悬赏园豆:50 [已解决问题] 解决于 2012-04-13 16:21
public partial class User {
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int ID { get; set; }

    [StringLength(30)]
    [Required]
    public string LoginName { get; set; }

    [StringLength(120)]
    [Required]
    [DataType(DataType.Password)]
    public string Pwd { get; set; }

    [StringLength(50)]
    public string Phone { get; set; }

    [StringLength(100)]
    public string WebSite { get; set; }
... ... 
}

如上面的示例代码所示, LoginName 和 Pwd 是 Required 的。

某些时候我只想更某些字段,比如在某个操作中,我只想更新 WebSite:

public void UpdateUser(User user , params string[] properties) {
        this.rep.DB.Users.Attach(user);
        this.rep.DB.Configuration.ValidateOnSaveEnabled = false;
        var entry = this.rep.DB.Entry(user);
        foreach(var prop in properties) {
            var entProp = entry.Property(prop);
            //var vas = entProp.GetValidationErrors(); entProp.IsModified = true;
        }
        this.rep.DB.SaveChanges();
        this.rep.DB.Configuration.ValidateOnSaveEnabled = true;
    }
var user = new User(){ ID = 1, WebSite = "http://www.stackoverflow.com" }
UpdateUser(user, "WebSite")

这样做,可以很好的运行,但是ValidateOnSaveEnabled 是 false, 如果将这个值设为 true ,就会因为 LoginName 和 Pwd 是 Required 的,而引起验证不通过。

有没有办法,在 ValidateOnSaveEnabled 为 true 的情况下,不去验证 LoginName 和 Pwd, 只验证 WebSite ?

谢谢

xling的主页 xling | 初学一级 | 园豆:6
提问于:2012-04-12 21:44
< >
分享
最佳答案
0

可以啊,方法有很多。千言万语不如一段代码,给段代码: 

    public class PartialValidationManager
    {

        private IDictionary<object, string[]> dictionary = new Dictionary<object, string[]>();
        
        //添加需要部分验证的实体对象
        public void Add(object entity, string[] propertyNames)
        {
            dictionary.Add(entity, propertyNames);
        }
        
        //移除需要部分验证的实体对象
        public void Remove(object entity)
        {
            dictionary.Remove(entity);
        }

        //对象是要我验证的吗?
        public bool IsResponsibleFor(object entity)
        {
            return dictionary.ContainsKey(entity);
        }

        //验证
        public void ValidateEntity(DbEntityValidationResult result)
        {
            var entry = result.Entry;

            foreach (var propertyName in dictionary[entry.Entity])
            {
                foreach (var error in entry.Property(propertyName).GetValidationErrors())
                {
                    result.ValidationErrors.Add(error);
                }
            }
        }
    }

    public class ....Context : DbContext
    {
//...
        public PartialValidationManager PVManager { get; private set; }
//...
        public BlogContext()
        {
            this.PVManager = new PartialValidationManager();
        }
//...
        protected override DbEntityValidationResult ValidateEntity(DbEntityEntry entry, IDictionary<object, object> items)
        {
            if (PVManager.IsResponsibleFor(entry.Entity))
            {
                var result = new DbEntityValidationResult(entry, new List<DbValidationError>());
                PVManager.ValidateEntity(result);
                return result;
            }
            else
            {
                return base.ValidateEntity(entry, items);
            }
        }
    }

然后, 调用的时候:

//....

    public void UpdateUser(User user , params string[] properties)
    {
        var entry = this.rep.DB.Entry(user);                

        this.rep.DB.PVManager.Add(user, properties);
        foreach(var prop in properties) {
            entry.Property(prop).IsModified = true;
        }
        this.rep.DB.SaveChanges();
        this.rep.DB.PVManager.Remove(user);
    }
//...好像有点不够robust, 自己改进吧
收获园豆:50
ChatinCode | 老鸟四级 |园豆:2272 | 2012-04-13 09:17
其他回答(2)
0

我目前是这样解决的,更新一个实体时,先attach这个实体(选择出来后进行attach操作),然后进行修改,最后用commit把更新提交到数据库

用这种方式不存在你遇到的问题,因为attach后该有的值都有了

artwl | 园豆:16536 (专家六级) | 2012-04-12 21:51

就是为了避免先取一次,我才这样做。

支持(0) 反对(0) xling | 园豆:6 (初学一级) | 2012-04-12 22:38

@xling: 哦,那我也关注下这个问题,看有没有更好的解决方案

支持(1) 反对(0) artwl | 园豆:16536 (专家六级) | 2012-04-12 22:39
0

一切皆有可能,这篇博文(EF Feature CTP5: Validation)中有答案

dudu | 园豆:37173 (高人七级) | 2012-04-13 10:21
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册