доступность объекта poco - PullRequest
0 голосов
/ 15 мая 2011

Я использую объекты poco, которые я написал с помощью Entity Framework.
Я хотел бы знать об уровнях доступности элементов, которые используются в качестве полей данных (элементов, которые сопоставлены полю в таблице из базы данных:
Длясущность с именем P:

public class P {
    public virtual long Id{get;set;}
    public virtual string Name{get;set;}
    public virtual long CompanyId{get;set;}
    public virtual Company Company{get;set;}
}

Должны ли участники быть публичными?
Должны ли участники быть виртуальными?
Могут ли участники быть частными?

Каковы правиладля доступности членов?

Ответы [ 4 ]

2 голосов
/ 15 мая 2011

Если вы хотите использовать объекты POCO с Entity Framework, чтобы они автоматически отслеживались, необходимо выполнить ряд требований, перечисленных здесь .

В частности, к вашему вопросу свойства должны быть объявлены как public и virtual, если вы хотите, чтобы ваш класс поддерживал отложенную загрузку (поскольку EF будет извлекать прокси-класс из вашего класса и переопределять свойства, чтобы обеспечить функциональность. )

2 голосов
/ 15 мая 2011

Зависит от используемой вами технологии связи.При использовании WCF (который использует DataContractSerializer) вы можете установить доступность для всего, что вы предпочитаете, и поставить атрибут [DataMember] над любым частным, защищенным или открытым полем или свойством.Затем они будут сериализованы при транспортировке.Если вы используете XmlSerializer, то только общие свойства будут сериализованы, и вы можете исключить свойства с атрибутом [XmlIgnore].

О виртуальном: виртуальный не имеет ничего общего с доступностью, а больше с ООП, предоставляя производным классам возможностьпереопределить объявленные свойства / методы.Это зависит от дизайна, который вам нужен / предпочтителен.

Итак, сначала подумайте о доступности полей / свойств, которые нужны вашим классам в сочетании с методом сериализации.

1 голос
/ 15 мая 2011

Модификатор доступа public помечает тип и член типа как доступные из внешних библиотек.Это означает, что если у вас есть тип в сборке A, и вы добавляете ссылку на него из сборки B, это означает, что вы можете получить доступ к этому типу / члену из типов, представленных в сборке B. Есть и другие модификаторы доступа (читайте о них here ).

Знание того, как модификаторы доступа изменяют поведение типов, является важной частью объектно-ориентированного проектирования.

virtual члены позволяют типу предоставлять реализацию по умолчанию дляконкретный функционал.Например, если бы у меня был тип:

public class Logger {
    protected virtual void Write(string message) {
        Console.Write(message);
    }
}

, я мог бы иметь тип:

public class DebugLogger : Logger {

}

Этот тип будет представлять мою реализацию по умолчанию Write как метод Logger.Write,Я мог (необязательно) переопределить это поведение:

public class DebugLogger : Logger {
    protected override void Write(string message) {
        Debug.Print(message);
    }
}

Использование этого использования virtual / override позволяет классам необязательно настраивать свое поведение, а когда Write вызывается со ссылкой, простой дляLogger экземпляр, будет вызвана правильная реализация (так, переопределенный метод в последнем случае).

private члены используются, чтобы содержать члены, которые не должны быть представлены вне родительского типа.Например, вспомогательное поле для свойства почти всегда будет закрытым.

Общее правило, которому я следую, таково:

  1. public члены предоставляют специфическую функциональность, которую я хочу использовать из внешних типов./assemblies.
  2. protected члены предоставляют специфическую функциональность, которую я хочу использовать только для наследования типов.
  3. private члены скрывают функциональность, которую я хочу содержать, только для родительского типа.Например, я хочу использовать метод, который специфичен для данного типа и не имеет никаких преимуществ для публичного показа.Например, методы мутации состояния, которыми я хочу управлять из внешнего доступа и т. Д.

Другие:

  1. internal позволяет мне помечать элементы как доступные только в сборке, котораясодержит их.Это полезно, когда вам нужно раскрыть такие вещи, как методы компоновщика и т. Д., Которые относятся к конкретной сборке, которые вы не хотите отмечать как публичные, но не можете использовать в качестве закрытых элементов.
  2. Я редко используюprotected internal.

Надеюсь, это поможет!

0 голосов
/ 15 мая 2011

Это сильно зависит от используемого вами подхода.

Модель / База данных в первую очередь:

  • Члены не должны быть публичными , но это имеетнекоторые последствия.Получатели и установщики свойств POCO должны иметь такую ​​же доступность, как определено в EDMX (показано в связанном ответе).Изменение доступности, скорее всего, повредит либо отслеживанию прокси, либо отложенной загрузке, либо обоим, как описано в ссылке, предоставленной @ dlev.
  • Члены не обязательно должны быть virtual.Если вы хотите ленивую загрузку, вы должны отметить все сопоставленные навигационные свойства virtual.Если вы хотите отслеживать прокси, вы должны отметить все остальные свойства virtual.

Сначала код (только EFv4.1):

  • В этом случае ситуация хуже.Участники должны быть public.В особом случае, когда сущность находится в той же сборке, что и элементы конфигурации контекста или сопоставления, может быть internal (я пропускаю InternalsVisibleTo, потому что это не очень хороший сценарий).В случае, когда конфигурация отображения является вложенным классом сущности, члены также могут быть private или protected, но это сильно нарушает весь смысл POCO, поскольку сущность POCO должна содержать зависимый от EF вложенный класс.Весь смысл в том, что отображение выполняется в коде и на него влияют правила доступности.
  • virtual ключевое слово имеет то же значение, что и в первых подходах Model и Database.

virtual ключевое слово необходимо, потому что EF создаст новый тип во время выполнения, полученный из типа объекта.Этот тип называется прокси и переопределяет поведение в свойствах get и set.В случае отложенной загрузки добавляется вызов операции Load, которая запускает загрузку отношения при первом обращении.В случае отслеживания изменений прокси информирует ObjectStateManager / DbChangeTracker о каждом изменении присоединенного объекта.Если отслеживающие прокси не используются, EF должен использовать отслеживание моментальных снимков, которое оценивает все изменения в присоединенном объекте во время сохранения, что считается гораздо более медленной операцией.

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