首先,让我们看看重写属性...
public override bool IsValid(object value)
{
var db = new CoinDataContext();
//Return whether none of the email contains the specified value
return db.Emails.Count(e => e.Email1 == value.ToString()) == 0;
}
此外,不需要转换(c == 0)
为布尔值,因为该操作的结果已经是布尔值。类型bool
是 的别名,Boolean
其方式与int
的别名相同Int32
。任何一个都可以接受。我自己更喜欢小写版本。
正如亚历克斯在他的回答中已经建议的那样,这不是确定电子邮件地址在进入数据库时是否唯一的可靠方法。只是在检查时它是唯一的。
最后,有点离题了……我写了一些 linq 扩展,比如下面的类。使用它可以让我将属性的返回重写为db.Emails.None(e => e.Email1 == value.ToString());
. 这使它更具可读性。
更新
如果不访问数据库并将行与写入的值进行比较,就无法确定数据库中值的唯一性。您仍然需要为数据库创建一个实例。不过,我要做的是将这些关注点分成服务层和数据层(与 MVC 网站项目分开的项目)等领域。您的数据层将专门处理与数据库有关的任何事情。如果您愿意,我可以写一些示例来说明如何将 CoinDataContext 与属性本身分开?
解决您的另一个问题,这里我们不需要在属性内进行查询,但您仍然需要调用数据库,并指定要使用的表。
但是,因为这是一个属性,所以我不能 100% 确定您是否可以在属性中使用 linq lambda 表达式,因此您的属性必须以这种方式保持泛化。
数据层项目
该层将包含与不同表相关的不同类。下面的课程专门用于电子邮件表。
电子邮件映射器类
public static class EmailMapper
{
public static void IsValid(Func<string, bool> query)
{
var db = new CoinDataContext();
return db.Emails.Count(query) == 0;
}
}
服务层项目
该层负责对象的一般验证,但也用于访问其他层,例如外部 API。
电子邮件服务类
public static class EmailService
{
public static IsValid(string address)
{
bool isValid = false;
//...Check email is valid first with regex. Not done.
isValid = RegexHelper.IsEmailAddressValid(address);
//Go to the database and determine it's valid ONLY if the regex passes.
return isValid ? EmailMapper.IsValid(x=> x.Email == address) : false;
}
}
Web项目中的属性类
public override Boolean IsValid(Object value)
{
return EmailService.IsValid(value.ToString());
}