我想详细阐述斯蒂芬克利里的答案。他在使用部分类/方法处理EF中的业务规则时是正确的。但是,他没有详细说明在该部分类/方法中应该做什么。我在我的博客上创建了一个URL缩短服务,以此作为示例。我的ShortURL
实体只有两列/属性。 Url
和ID
。
我想验证缩短的URL是一个有效的URL,然后通过EF实际存储在数据库中。所以我创建了如下的部分类和方法:
public partial class ShortURL
{
partial void OnUrlChanging(string url)
{
if (!Regex.IsMatch(url, @"(^((http|ftp|https):\/\/|www\.)[\w\-_]+(\.[\w\-_]+)+([\w\-\.,@?^=%&:/~\+#]*[\w\-\@?^=%&/~\+#])?)"))
throw new Exception("Not a valid URL.");
}
}
这会停止EF更改属性,使其保留为NULL。但这就是它所做的一切。它并没有给我一个简单的方法来获取错误信息并将其显示给用户(我知道编辑:根据http://www.sellsbrothers.com/posts/Details/12700 IDataErrorInfo是获取错误消息在ASP中正确显示的唯一方法。 NET MVC),所以我遵循了另一个例子,我在网络的黑暗凹处找到了某个地方,并且让我的部分类继承自IDataErrorInfo
。然后我实现了接口并包含一个专用字典对象来存储错误消息。
public partial class ShortURL : IDataErrorInfo
{
private Dictionary<string, string> errors = new Dictionary<string, string>();
partial void OnUrlChanging(string url)
{
if (!Regex.IsMatch(url, @"(^((http|ftp|https):\/\/|www\.)[\w\-_]+(\.[\w\-_]+)+([\w\-\.,@?^=%&:/~\+#]*[\w\-\@?^=%&/~\+#])?)"))
errors.Add("Url", "Not a valid URL.");
}
public string Error
{
get { return string.Empty; } //I never use this so I just return empty.
}
public string this[string columnName]
{
get
{
if (errors.ContainsKey(columnName))
return errors[columnName];
return string.Empty; //Return empty if no error in dictionary.
}
}
}
现在,我有一个全功能的方式来存储,检索和显示错误消息。现在回到我的控制器(在MVC中)我能够做到if (!ModelState.IsValid)
[HttpPost]
public ViewResult URLShortener(ShortURL shortURL)
{
if (!ModelState.IsValid)
return View();
shortURL.Url = shortURL.Url.ToLower().StartsWith("www.") ? "http://" + shortURL.Url : shortURL.Url;
shortURLRepository.AddShortURL(shortURL);
object model = "http://www.u413.com/" + ShortCodes.LongToShortCode(shortURL.UrlID);
//Not related to this answer but I had to cast my string as a generic object because the View() method has a (string, string) constructor that does something totally different. My view actually uses string as the model. I know I know, I could have just used ViewBag.
return View("ShowUrl", model);
}
有你去。一个如何扩展EF的部分方法的工作示例,以及如何将验证传播回UI。如果有任何需要改进的地方,或者我错过了某些东西,请告诉我。
是你的实体框架类还是你的域模型?或者你有单独的课程? – RPM1984 2011-02-10 00:39:39
您是使用实体对象还是POCO? – 2011-02-10 08:46:44
@Ladislav:我从Visual Studio 2010使用`EF` – Xaqron 2011-02-10 12:30:45