Чи вільні інтерфейси більш гнучкі, ніж атрибути, і чому?


15

У першому підручнику з коду EF 4.1 наведено наступний код:

public class Department
{
    public int DepartmentId { get; set; }
    [Required]
    public string Name { get; set; }
    public virtual ICollection<Collaborator> Collaborators { get; set; }
}

Потім пояснюється, що плавний інтерфейс є більш гнучким:

Анотації даних, безумовно, прості у використанні, але бажано використовувати програмний підхід, який забезпечує набагато більшу гнучкість.

Далі наведено приклад використання вільного інтерфейсу:

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.Entity<Department>().Property(dp => dp.Name).IsRequired();
    modelBuilder.Entity<Manager>().HasKey(ma => ma.ManagerCode);
    modelBuilder.Entity<Manager>().Property(ma => ma.Name)
        .IsConcurrencyToken(true)
        .IsVariableLength()
        .HasMaxLength(20);
}

Я не можу зрозуміти, чому вільний інтерфейс нібито кращий. Це насправді? З моєї точки зору, схоже, що анотації до даних є більш чіткими і мають більше чистого семантичного відчуття.

Моє запитання: чому міг би вільний інтерфейс бути кращим варіантом, ніж використання атрибутів, особливо в цьому випадку?

(Примітка. Я зовсім новачок у всій концепції вільних інтерфейсів, тому, будь ласка, не очікуйте, що попередніх знань щодо цього немає.)

Довідка: http://codefirst.codeplex.com/


Це питання дійсно не стосується вільних інтерфейсів. Різниця полягає у використанні атрибутів та звичайного коду. Якби код не вільно говорив, він не сильно змінить ваше запитання.
svick

Плавні інтерфейси @svick - це в основному нормальний код, але це виражається по-іншому. Ми віддалилися від вказівки речей у простому коді до атрибутів, тепер, маючи вільні інтерфейси, схоже, деякі повторюються і рухаються до того, щоб знову вказати речі в коді. Я просто хочу зрозуміти, чому б ви використовували код замість атрибутів. Чи вимагає вільних інтерфейсів відсторонення від атрибутів і назад, щоб просто знову кодувати все?
Тярт

Відповіді:


13

Анотації даних є статичними, наприклад, цей спосіб оголошення не може змінюватися під час виконання:

  [MinLength(5)]
  [MaxLength(20,ErrorMessage="Le nom ne peut pas avoir plus de 20 caractères")]
  public new string Name { get; set; }

Вільний інтерфейс може бути динамічним:

   if (longNamesEnabled)
   {
      modelBuilder.Entity<Manager>().Property(ma => ma.Name)
        .HasMaxLength(100);
   }
   else
   {
      modelBuilder.Entity<Manager>().Property(ma => ma.Name)
        .HasMaxLength(20);
   }

не кажучи вже про код, можна використовувати повторно між властивостями.


2
чому ви думаєте, що довжина (або будь-яка інша властивість) тієї ж властивості буде змінюватися під час виконання?
Юсубов

1
@ElYusubov: Я б почав із тих сценаріїв, коли я не знав довжини поля під час кодування.
Wyatt Barnett

@WyattBarnett: може мати сенс мати довжину поля як змінну лише тоді, коли параметри домену динамічно вибираються з якоїсь служби або зовнішнього джерела, який не вводиться. Однак для динамічного поводження з властивостями домену потрібен захисний підхід до кодування.
Юсубов

1
@ElYusubov у вас може бути два властивості, які повинні бути абсолютно однаковими, за винятком довжини, тому я передаю їх у функцію, яка динамічно налаштовує їх. Ось чому автор назвав їх більш гнучкими.
Гарретт Холл

1
@ElYusubov, ви можете встановити довжину поля в налаштуваннях проекту, яке подається в app.config або web.config. Потім, якщо довжина поля бази даних змінилася, ви можете змінити довжину у файлі .config без перекомпіляції та повторного використання програми.
Kyralessa

8

Я не думаю, що це твердження слід широко застосовувати; він дуже специфічний для Кодексу Першого. У Code First, анотації даних містять лише підмножину функціональних можливостей, доступних у вільному API. Іншими словами, є певні модельні конфігурації, які можна виконати лише за допомогою вільного API.

Наприклад, ось деякі речі, які неможливо вказати за допомогою приміток:

  • Точність властивості DateTime
  • Точність та масштабність числових властивостей
  • Властивість String або Binary як фіксованої довжини
  • Властивість String як не-унікод
  • Поведінка на видалення відносин
  • Розширені стратегії картографування

Особисто я схильний використовувати анотації даних, пов’язаних з валідацією, коли це можливо, оскільки інші технології, такі як MVC, також можуть скористатися ними. Для всього іншого я віддаю перевагу вільному API.


Чи можете ви навести приклад того, що можна зробити лише за допомогою вільного API? Також було б цікаво дізнатися, чому вони вирішили зробити це саме так. Я намагаюся зрозуміти прості API-інтерфейси порівняно зі звичайними методами та структурою сутності - лише приклад. Я хочу знати, чому вони вважають за краще це перед атрибутами. Мені атрибути здаються більш правильними і читабельними.
Тяртарт

1
@Tjaart Я додав кілька прикладів. Розробляючи це, існували два основні мотиваційні принципи. По-перше, дозвольте розробникам вибирати. Деякі люди сприймають атрибути як порушення POCO, інші люблять їх декларативний характер. По-друге, використовуйте існуючі атрибути і вводьте лише нові для загальних сценаріїв. Ви, мабуть, погоджуєтесь, що приклади, які я наводив вище, відносно рідкісні.
бричелам

Я помітив, що поведінка OnDelete, здається, доступна лише у вільному API. Ви можете подумати, чому вони вирішили зробити це саме так? Це справді те, що я намагаюся досягти з цим питанням. Порушення POCO може бути вагомою причиною, якщо ви розділяєте класи між проектами. Ви можете перетворити на залежність від сутності, яка вам не потрібна, якщо ви використовуєте атрибути!
Тярт

@Tjaart, я не пам'ятаю точних причин. Я приєднався до команди до кінця функції Code First, і не був тут, бо це дизайн. Я побачу, чи можу я змусити когось із команди зважити.
бричелам

1

Відповідь на ваше запитання надається за посиланням.

Потім ви визначаєте свої обмеження, застосовні до вашого домену в рамках цього методу програмно.

В основному, більш-менш переважно використовувати атрибути проти програмного підходу, де програмний підхід має більше контролю над сутністю. Однак існує спеціальний спосіб додавання атрибутів для прикраси вашої моделі, який ви також можете виглядати.

Використовуючи такий підхід, ви навіть можете описати відносини між таблицями та стовпцями. Підсумок, якщо ви бажаєте мати більш тонкий контроль над своїм доменом, ви можете використовувати цей новий підхід, який постачається з EF4.1.

Однак для загальних сценаріїв перевірки застосування атрибутів має працювати добре, оскільки це надійно охоплює більшість випадків; і крім того, це може заощадити ваш час.


Чи можете ви проілюструвати, як програмний спосіб дає вам більше контролю? Я не дуже розумію це на даний момент.
Тяртарт

Наприклад, візьміть це ".IsConcurrencyToken (true)" - як би ви це зробили за визначенням Attribute?
Юсубов

[ConcurrencyCheck] <- що насправді здається простішим
Tjaart

хороший улов, як би ви потім описали "відносини між таблицями та стовпцями"?
Юсубов

[ForeignKey ("PersonId")] <- так, що, мабуть, не так просто, як .HasForeignKey (t => t.ProjectId), хоча все, що потрібно, це дозволити ForeignKey () взяти лямбда так само, як вільний інтерфейс. Це ще не пояснює, чому один кращий за інший.
Тяртарт

0

Думаю, що вони рекомендують вільний API для перших реалізацій коду, оскільки ви чітко описуєте, як створюються відносини в базі даних. Якщо ви використовуєте примітки про дані, база даних, створена Entity Framework, може бути не такою, яку ви очікуєте. Ваш початковий приклад дуже простий, тому, як і ви, я б просто використовував метод анотації даних.


Чи можете ви навести приклад того, що база даних не є такою, яку ви очікуєте, і як вільний інтерфейс запобігає цьому?
Тярт
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.