Расширение классов структуры сущностей - PullRequest
2 голосов
/ 10 февраля 2011

Даже много вопросов и ответов по этому вопросу, я не нашел четкого ответа на этот вопрос:

Какова наилучшая практика проектирования для добавления бизнес-правил (т. Е. Проверок) в классы сущностей.

Я просто хочу проверить некоторые проверки перед установкой значения базовой сущности:

public Property
{
    get { return base.Property; }
    set
    {
       // Do some validations or other business logic
       base.Property = value;
    }
}

Нет смысла создавать новый класс с нуля в BLL, когда все свойства уже есть в классе сущностей. С другой стороны, классы сущностей должны быть расширены с помощью правил бизнес-логики.

Использование интерфейса требует дополнительной работы, поскольку изменение в DAL (сущности) будет отражено как в интерфейсе, так и в классе BLL.

Я не уверен, является ли хорошей идеей наследование от класса сущности и переопределение его свойств и добавление дополнительных свойств и методов.

Пример псевдокода более полезен для меня.

Спасибо

Ответы [ 3 ]

4 голосов
/ 11 февраля 2011

Я хотел бы уточнить ответ Стивена Клири. Он прав в использовании частичного класса / методов для обработки бизнес-правил в 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\-\.,@?^=%&amp;:/~\+#]*[\w\-\@?^=%&amp;/~\+#])?)"))
            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, но и как распространить валидацию обратно в пользовательский интерфейс. Дайте мне знать, если что-то нуждается в улучшении или я что-то пропустил.

3 голосов
/ 10 февраля 2011

Проверьте код, сгенерированный дизайнером EF.

Каждое свойство Property фактически реализовано так:

    public global::System.String Property
    {
        get
        {
            return _Property;
        }
        set
        {
            OnPropertyChanging(value);
            ReportPropertyChanging("Property");
            _Property = StructuralObject.SetValidValue(value, false);
            ReportPropertyChanged("Property");
            OnPropertyChanged();
        }
    }
    private global::System.String _Property;
    partial void OnPropertyChanging(global::System.String value);
    partial void OnPropertyChanged();

Частичный метод On-Property-Changing - это то, где вы можете сделать одинпроверка правильности или бизнес-логика.

2 голосов
/ 10 февраля 2011

Xaqron, я нашел лучший способ использовать частичные классы, например, если у вас есть класс в EF с именем PropertyListing, вы можете использовать частичный класс, например:

Partial Public Class PropertyListing
    Inherits EntityObject

    'Do something here

End Class

Вы можететеперь расширяйте класс настолько, насколько вам нужно, без особой суеты.Пример написан на VB, но вы получаете его суть

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...