我无法想出一个更好的方式来标题我的标题,它可能是我刚才所做的最准确的描述。这个问题是最佳实践和编码风格的混合。
我基本上有一个WPF应用程序,它使用MVVMLight库和Entity Framework(6.x)以及数据库的第一个工作流程。
从数据库生成的一个POCO类有大约44列,请记住这一点。
用于验证此特定对象。我使用实现IDataErrorInfo的部分类来扩展POCO对象的功能,如下所示:
public partial class MyClass : IDataErrorInfo { ... }
现在这没关系,直到你记得这个对象有44个字段。这将给我一个索引器,它将成为180多行if语句。
这对我来说只是尖叫不好的编程习惯。这个索引器的结构如下所示:
public string this[string columnName]
{
get
{
switch (columnName)
{
case "Column1":
if (string.IsNullOrWhiteSpace(Column1))
return "A value for Column1 is required.";
// More if-statements here...
break;
case "Column2":
// Same as above.
break;
// There's going to be about another 42 cases here...
}
return null;
}
}
我考虑过的其他事情是将if语句分解为单独的方法,这会减少索引器中的行数,但会引入40多个方法,这些方法都具有相同的结构。
// In the indexer.
switch(columnName)
{
case "Column1":
return ValidateColumn1();
break;
case "Column2":
return ValidateColumn2();
break;
}
// Somewhere a bit further down the class...
private string ValidateColumn1()
{
if (string.IsNullOrWhiteSpace(Column1))
return "A value for Column1 is required.";
// More if-statements...
}
private string ValidateColumn2()
{
// Ditto.
}
我可以理解,有些人可以在WPF / EF中进行验证,例如:
但我很好奇最好的方法是什么,因为200多行索引器和创建40多个方法/类似乎是一种非常错误的方法。
我知道我可能会在这里提出多个问题,但这是我试图理解的内容:
提前致谢。
答案 0 :(得分:1)
这是一种方法(我通常这样做)。 我使用EF数据注释(在我的例子中,我使用EF数据注释映射每个实体,并使用EF流畅的接口进行关系)。 我通常从标准IDataErrorInfo的EntityBase继承。 这是我的EntityBase的一部分
public class EntityBase : IDataErrorInfo
{
public virtual bool IsValid()
{
return GetValidationErrors() == string.Empty;
}
protected virtual string GetValidationErrors()
{
var vc = new ValidationContext(this, null, null);
var vResults = new List<ValidationResult>();
if (!Validator.TryValidateObject(this, vc, vResults, true))
return vResults.Aggregate("", (current, ve) => current + (ve.ErrorMessage + Environment.NewLine));
return "";
}
protected virtual string GetValidationErrors(string columnName)
{
var vc = new ValidationContext(this, null, null);
var vResults = new List<ValidationResult>();
if (!Validator.TryValidateObject(this, vc, vResults, true))
{
string error = "";
foreach (var ve in vResults)
{
if (ve.MemberNames.Contains(columnName, StringComparer.CurrentCultureIgnoreCase))
error += ve.ErrorMessage + Environment.NewLine;
}
return error;
}
return "";
}
string IDataErrorInfo.Error
{
get { return GetValidationErrors(); }
}
string IDataErrorInfo.this[string columnName]
{
get { return GetValidationErrors(columnName); }
}
}
有些实体需要复杂的属性验证(即交叉属性验证)。在这种情况下,我覆盖虚拟方法并向实体添加特定验证