[英]poco object Accessibility
I am using poco objects I wrote with entity framework. 我正在使用通过实体框架编写的poco对象。
I would like to know about the accessibility levels of the members that used as data fields (members that mapped to field in table from the database: 我想了解用作数据字段的成员(从数据库映射到表中字段的成员的可访问性级别:
For entity named P: 对于名为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;}
}
Does the members must be public? 成员必须公开吗?
Does the members must be virtual? 成员必须是虚拟的吗?
Does the members can be private? 成员可以私人吗?
What are the rules for the members accessibility? 成员可访问性的规则是什么?
Depends on the communication technology you are using. 取决于您使用的通信技术。 When using WCF (which uses
DataContractSerializer
) you can set the accessibility to anything you prefer and put the [DataMember]
attribute above any private, protected or public field or property. 使用WCF(使用
DataContractSerializer
)时,可以将访问权限设置为您喜欢的任何内容,并将[DataMember]
属性放在任何私有,受保护或公共字段或属性之上。 These will then be serialized when transporting the poco's. 然后在运输poco时将这些序列化。 If you use
XmlSerializer
only the public properties will be serialized and you can exclude properties with [XmlIgnore]
attribute. 如果使用
XmlSerializer
仅公共属性将被序列化,并且可以使用[XmlIgnore]
属性排除属性。
About virtual: virtual has nothing to do with accessibility but more with OOP by giving derived classes the possibility to override the declared properties / methods. 关于虚拟:虚拟与可访问性无关,而与OOP无关,它通过为派生类提供重写声明的属性/方法的可能性。 This depends on the design that you need / prefer.
这取决于您需要/喜欢的设计。
So first think about the accessibility of the fields / properties that your classes need in combination with the serialization technique to be used. 因此,首先考虑一下您的类需要结合使用的序列化技术来访问字段/属性。
If you want to use POCO objects with Entity Framework so that they are auto-tracked, there are a number of requirements that have to be met, which are listed here . 如果要将POCO对象与Entity Framework一起使用,以便对其进行自动跟踪,则必须满足许多要求,这些要求在此处列出。
To your question specifically, properties must be declared as public
and virtual
if you want your class to support lazy loading (since the EF will derive a proxy class from your class and override the properties to provide the functionality.) 特别是对于您的问题,如果您希望您的类支持延迟加载,则必须将属性声明为
public
和virtual
(因为EF将从类中派生代理类并覆盖属性以提供功能)。
The public
access modifier marks a type and a member of a type as accessible from external libraries. public
访问修饰符将类型和类型的成员标记为可从外部库访问。 This means if you have a type in assembly A, and you add a reference to it from assembly B, it means you can access that type/member from types exposed in assembly B. There are other access modifiers (read up about them here ). 这意味着,如果程序集A中有一个类型,并且从程序集B中添加了对该类型的引用,则意味着您可以从程序集B中公开的类型访问该类型/成员。还有其他访问修饰符( 在此处进行阅读) 。
Knowing how access modifiers change the behaviour of types is an important part of object orientated design. 知道访问修饰符如何改变类型的行为是面向对象设计的重要部分。
virtual
members allow a type to provide a default implementation of specific functionality. virtual
成员允许一种类型提供特定功能的默认实现。 For example, if I had a type: 例如,如果我有一个类型:
public class Logger {
protected virtual void Write(string message) {
Console.Write(message);
}
}
I could have a type: 我可以有一个类型:
public class DebugLogger : Logger {
}
That type will expose my default implementation of Write
as the method Logger.Write
. 该类型将把我的默认
Write
实现公开为Logger.Write
方法。 I could (optional) override this behaviour: 我可以(可选)覆盖此行为:
public class DebugLogger : Logger {
protected override void Write(string message) {
Debug.Print(message);
}
}
Using this use of virtual
/ override
allows classes to optional customise their behaviour, and when Write
is called with a reference simple to a Logger
instance, the correct implementation will be called (so, the overriden method in the latter case). 使用
virtual
/ override
这种使用允许类可选地自定义其行为,并且当使用Logger
实例的简单引用来调用Write
时,将调用正确的实现(因此,在后一种情况下,重写方法)。
private
members are used to contain members that should not be exposed outside of the parent type. private
成员用于包含不应在父类型之外公开的成员。 Eg a backing field for a property will almost always be private. 例如,财产的背景几乎总是私有的。
The general rule I follow is: 我遵循的一般规则是:
public
members expose specific functionality I want to be usable from external types/assemblies. public
成员公开了我希望可以从外部类型/程序集中使用的特定功能。 protected
members expose specific functionality I want to be usable from inheriting types only. protected
成员公开特定的功能,我希望仅可用于继承类型。 private
members hide functionality that I want to contain to just the parent type. private
成员将我想包含的功能隐藏到父类型中。 Eg I want a use a method which is specific to the type and has no benefi being exposed publicly. Others: 其他:
internal
allows me to mark members as accessible within only the assembly that contains them. internal
使我可以将成员标记为只能在包含它们的程序集中访问。 This is useful when you need to expose things like builder methods, etc. which are specific to the containing assembly, that you don't want to mark as public but cannot be used as private members. protected internal
. protected internal
。 Hope that helps! 希望有帮助!
This strongly depends on the approach you are using. 这在很大程度上取决于您使用的方法。
virtual
. virtual
。 If you want lazy loading you must mark all mapped navigation properties virtual
. virtual
。 If you want tracking proxies you must mark all other properties virtual
. virtual
。 public
. public
。 In special case when entity is in the same assembly as context or mapping configuration members can be internal
(I skip InternalsVisibleTo
because it is not very nice scenario). internal
(我跳过InternalsVisibleTo
因为这不是很好的情况)。 In case when mapping configuration is nested class of entity, members can be also private
or protected
but this strongly breaks whole meaning of POCO because POCO entity must contain EF dependent nested class. private
或protected
但这会严重破坏POCO的全部含义,因为POCO实体必须包含EF依赖的嵌套类。 The whole point is that mapping is done in code and it is affected by accessibility rules. virtual
keyword has same meaning as in Model and Database first approaches. virtual
关键字的含义与“模型和数据库”优先方法中的含义相同。 virtual
keyword is needed because EF will create new type at runtime derived from entity type. 由于EF会在运行时从实体类型派生新类型,因此需要
virtual
关键字。 This type is referred as proxy and it overrides behaviour in property getter and setter. 此类型称为代理,它覆盖属性getter和setter中的行为。 In case of lazy loading it adds call to
Load
operation which triggers loading of relation when accessed first time. 在延迟加载的情况下,它会向
Load
操作添加调用,该调用在首次访问时触发关系的加载。 In case of change tracking proxies it informs ObjectStateManager
/ DbChangeTracker
about each change to attached entity. 如果发生更改跟踪代理,它将向
ObjectStateManager
/ DbChangeTracker
通知对附加实体的每次更改。 If tracking proxies are not used EF must use snapshot tracking which evaluates all changes to attached entity during saving which is considered as much slower operation. 如果不使用跟踪代理,则EF必须使用快照跟踪来评估保存过程中对连接实体的所有更改,这被认为操作速度较慢。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.