首先为 EF 代码的 CTP5 关闭 ProxyCreationEnabled 有什么缺点
我的 WCF 服务从代码优先模型返回类的唯一方法是使用以下代码将 ProxyCreationEnable 设置为 false。
((IObjectContextAdapter)MyDb).ObjectContext.ContextOptions.ProxyCreationEnable = false;
这样做会带来什么负面后果?一个好处是我至少可以序列化这些动态类型,以便可以使用 WCF 通过线路发送它们。
The only way that my WCF service can return classes from a code first model is by setting the ProxyCreationEnable
to false
using the code below.
((IObjectContextAdapter)MyDb).ObjectContext.ContextOptions.ProxyCreationEnable = false;
What are the negative consequences of doing this? One gain is that I can at least get these dynamic types serialized so they can be sent over the wire using WCF.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
如果 DbContext.Configuration.ProxyCreationEnabled 设置为 false,DbContext 将不会加载某些父对象的子对象,除非在父对象上调用 Include 方法。将 DbContext.Configuration.LazyLoadingEnabled 设置为 true 或 false 不会对其行为产生影响。
如果
DbContext.Configuration.ProxyCreationEnabled
设置为true
,子对象将自动加载,并且DbContext.Configuration.LazyLoadingEnabled
值将控制子对象何时加载对象已加载。If
DbContext.Configuration.ProxyCreationEnabled
is set tofalse
, DbContext will not load child objects for some parent object unlessInclude
method is called on parent object. SettingDbContext.Configuration.LazyLoadingEnabled
totrue
orfalse
will have no impact on its behaviours.If
DbContext.Configuration.ProxyCreationEnabled
is set totrue
, child objects will be loaded automatically, andDbContext.Configuration.LazyLoadingEnabled
value will control when child objects are loaded.动态代理用于更改跟踪和延迟加载。当 WCF 尝试序列化对象时,相关上下文通常会关闭并处置,但导航属性的序列化将自动触发延迟加载(在关闭上下文上)=>例外。
如果关闭延迟加载,则需要对要使用的所有导航属性使用预先加载(包括在 ObjectQuery 上)。跟踪更改不适用于 WCF,它仅适用于附加到 ObjectContext 的实体的修改。
Dynamic proxies are used for change tracking and lazy loading. When WCF tries to serialize object, related context is usually closed and disposed but serialization of navigation properties will automatically trigger lazy loading (on closed context) => exception.
If you turn off lazy loading you will need to use eager loading for all navigation properties you want to use (Include on ObjectQuery). Tracking changes doesn't work over WCF it works only for modification of entity which is attached to ObjectContext.
当您使用 EF 时,它会默认为您的类创建一个代理。解决方案可以是在 DbContext 类的构造函数中添加此行。您的数据模型继承自 DbContext 类,因此您可以像这样编辑您的模型:
该类位于您的
EF.edmx
中,然后位于yourmodel.Context.tt
中,然后 <代码>yourmodel.Context.csWhen you use EF, it creates a proxy by default for your class. A solution can be to add this line in the constructor of your DbContext class. Your data model inherited from the DbContext class, so you can edit your model like this:
This class is in your
EF.edmx
then in theyourmodel.Context.tt
thenyourmodel.Context.cs
(使用 Visual Studio 2013 或更高版本)
为了避免每次从数据库刷新模型时编辑 EF 模型中的类构造函数,或以其他方式触发代码重建,执行更改的正确位置是负责实际创建模型代码的 T4 代码文件。
几年前,当我了解类和属性实际创建的基本机制时,我遇到了一些关于动态属性的其他问题。 T4!!!这是多么奇迹啊:-D
T4 语法一开始可能有点令人生畏,因此阅读语法是明智的。做出改变时非常专注也是一个好主意:-)
所以!如果您查看模型,您会发现 .edmx 文件下有一个 .tt 文件。此 .tt (T4) 文件是实际创建模型类的脚本。每次构建模型或在模型编辑器中进行一些更改时,该脚本都会自动运行。
假设您的模型描述符名为 Model1.edmx。
在其下方的树中将有一个名为 Model1.Context.tt 的文件。您还将看到一个 Model1.Context.cs 文件。这显然是您的上下文的实际代码文件。但这个文件是运行.tt脚本文件的结果!它是完全动态创建的。所以不知道编辑它。
打开 .tt 文件,您将看到类似以下内容:
另外 50 行左右,构造函数代码正在编写脚本。
我添加了属性
base.Configuration.ProxyCreationEnabled = false;
,以便它将成为构造函数中的第一行。保存文件,然后打开 Model1.Context.cs 文件以查看生成的代码。
如果要强制运行模板脚本,请选择菜单
很容易知道您在 T4 代码中是否犯了错误,因为 .cs 文件要么根本没有生成,要么在编辑器中打开它时出现明显错误。
(Using Visual Studio 2013 or later)
To avoid the edit of the class constructor in your EF model every time you refresh the model from the database, or some other way trigger the rebuild of the code, the proper place to do the change is in the T4 code file that is responsible of actually creating the model code.
I had some other issue with dynamic properties a few years back when I understood the underlying mechanics of how the classes and properties was actually created. T4!!! What a miracle it is :-D
T4 syntax can be a bit intimidating at first, so reading up on the syntax is wise. Being VERY focused when making changes is also a good idea :-)
So! If you look in your model, you have a .tt file under your .edmx file. This .tt (T4) file is the script that actually creates your model class. The script will be run automatically each time you build your model or make some changes in the model editor.
Let's say your Model descriptor is named Model1.edmx.
You will have a file named Model1.Context.tt in the tree under it. You will also see a Model1.Context.cs file. This is obviously the actual code file for your context. But this file is the result of the .tt script file being run! It is completely dynamically created. So no idea editing it.
Open the .tt file and you will see something like:
Another 50 or so lines down, the constructor code is being scripted.
I have added the property
base.Configuration.ProxyCreationEnabled = false;
so that it will be the very first line in the constructor.Save your file, and open the Model1.Context.cs file to see the resulting code.
If you want to force the template script to run, select the menu
It is easy to know if you've made a mistake in your T4 code, as the .cs file will be either not made at all, or with obvious errors if you open it in the editor.