序列化类和EF动态代理 - 怎么样? [英] Serializable classes and dynamic proxies in EF - how?

查看:574
本文介绍了序列化类和EF动态代理 - 怎么样?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

[A previous发布] ,我是被陷害的路径上有克隆我的实体。这个我已经尝试与序列化的方式做,因为在 [$ C $的CProject]

In [a previous posting], I was set on the path to having to clone my entities. This I've attempted to do with a serialisation approach as found in [codeproject].

因为类是由实体框架生成的,我单独做记号在这样一个自定义的.cs:

because the classes are generated by Entity Framework, I mark them up separately in a custom .cs like this:

[Serializable]
public partial class Claims
{
}

然而

,当检查(在克隆法):

however, when the check (in the clone method):

if (Object.ReferenceEquals(source, null))
{

被击中,我得到的错误:

gets hit, I get the error:

System.ArgumentException was unhandled by user code
  Message=The type must be serializable.
Parameter name: source
  Source=Web
  ParamName=source
  StackTrace:
       at .Web.Cloner.Clone[T](T source) in C:\Users\.\Documents\Visual Studio 2010\Projects\.\Website\Extensions.Object.cs:line 49
       at .Web.Models.Employer..ctor(User u) in C:\Users\.\Documents\Visual Studio 2010\Projects\.\Website\Models\EF.Custom.cs:line 121
       at .Web.Controllers.AuthController.Register(String Company, String GivenName, String Surname, String Title, String Department) in C:\Users\.\Documents\Visual Studio 2010\Projects\.\Website\Controllers\AuthController.cs:line 119
       at lambda_method(Closure , ControllerBase , Object[] )
       at System.Web.Mvc.ActionMethodDispatcher.Execute(ControllerBase controller, Object[] parameters)
       at System.Web.Mvc.ReflectedActionDescriptor.Execute(ControllerContext controllerContext, IDictionary`2 parameters)
       at System.Web.Mvc.ControllerActionInvoker.InvokeActionMethod(ControllerContext controllerContext, ActionDescriptor actionDescriptor, IDictionary`2 parameters)
       at System.Web.Mvc.ControllerActionInvoker.<>c__DisplayClass15.<InvokeActionMethodWithFilters>b__12()
       at System.Web.Mvc.ControllerActionInvoker.InvokeActionMethodFilter(IActionFilter filter, ActionExecutingContext preContext, Func`1 continuation)
  InnerException: 

所以显然我的,而类声明是serialisable,由EF生成的动态代理是不是......不知我的装饰品没有流过。

so apparently whilst my class Claims is serialisable, the dynamic proxies generated by EF are not... somehow my decorations are not flowing through.

有什么诀窍吗?

*更新I *

有关更多上下文:我有一个类用户包含定义为<$ C $属性声明 C>的ICollection&LT;权利要求GT; 。做克隆时,获取传递的类型是集合,而不是要求 - 这解释了为什么克隆抱怨的类型不是可序列化。所以现在的问题是:如何使 User.Claims 序列化的,因为我不能装点属性

for more context: I have a class User which contains a property Claims defined as an ICollection<Claim>. when doing the cloning, the type that gets passed is the collection, not Claim - this explains why the cloner is complaining that the type is not serializable. so the question now is: how do I make User.Claims serializable since I can't decorate a property?

Error   1   Attribute 'Serializable' is not valid on this declaration type.
It is only valid on 'class, struct, enum, delegate' declarations.   
C:\Users\.\Documents\Visual Studio 2010\Projects\.\Website\Models\EF.Custom.cs
128 10  Website

*更新II *

演习的重点是设施深层复制。这是什么样子:

the point of the exercise is to facility a deep copy. this is what it looks like:

public partial class Employer
{
    public Employer(User u)
    {
        this.Id = u.Id;
        this.GivenName = u.GivenName;
        this.Surname = u.Surname;
        this.Claims = u.Claims.Clone();
        this.Contacts = u.Contacts.Clone();
    }
}

为了让 u.Claims.Clone()工作 u.Claims 必须是可序列化,但它不是上面提到的原因。

in order for the u.Claims.Clone() to work, u.Claims must be serializable but it's not for the reasons cited above.

*更新III *

好吧,我改变了做法,实施这样的构造:

ok, I changed approach, implementing the constructor like this:

public partial class Employer
{
    public Employer(User u)
    {
        this.Id = u.Id;
        this.GivenName = u.GivenName;
        this.Surname = u.Surname;

        ICollection<Claim> cs = new List<Claim>();
        foreach (Claim c in u.Claims)
        {
            cs.Add(c.Clone());
        }
        this.Claims = cs;

和现在它得到过去的clone()的检查(如果线以上),但现在它打破的:

and now it gets past the clone()'s check ("if" line above), but now it breaks at:

formatter.Serialize(stream, source);

System.Runtime.Serialization.SerializationException was unhandled by user code
  Message=Type 'System.Data.Entity.DynamicProxies.User_7B7AFFFE306AB2E39C07D91CC157792F503F36DFCAB490FB3333A52EA1D5DC0D' in Assembly 'EntityFrameworkDynamicProxies-Web, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' is not marked as serializable.
  Source=mscorlib
  StackTrace:
       at System.Runtime.Serialization.FormatterServices.InternalGetSerializableMembers(RuntimeType type)
       at System.Runtime.Serialization.FormatterServices.GetSerializableMembers(Type type, StreamingContext context)
       at System.Runtime.Serialization.Formatters.Binary.WriteObjectInfo.InitMemberInfo()
       at System.Runtime.Serialization.Formatters.Binary.WriteObjectInfo.InitSerialize(Object obj, ISurrogateSelector surrogateSelector, StreamingContext context, SerObjectInfoInit serObjectInfoInit, IFormatterConverter converter, ObjectWriter objectWriter, SerializationBinder binder)
       at System.Runtime.Serialization.Formatters.Binary.ObjectWriter.Write(WriteObjectInfo objectInfo, NameInfo memberNameInfo, NameInfo typeNameInfo)
       at System.Runtime.Serialization.Formatters.Binary.ObjectWriter.Serialize(Object graph, Header[] inHeaders, __BinaryWriter serWriter, Boolean fCheck)
       at System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Serialize(Stream serializationStream, Object graph, Header[] headers, Boolean fCheck)
       at System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Serialize(Stream serializationStream, Object graph)
       at Skillscore.Web.Cloner.Clone[T](T source) in C:\Users\.\Documents\Visual Studio 2010\Projects\.\Website\Extensions.Object.cs:line 62
       at Skillscore.Web.Models.Employer..ctor(User u) in C:\Users\.\Documents\Visual Studio 2010\Projects\.\Website\Models\EF.Custom.cs:line 130

叹息......是一切总是那么难?

sigh... is everything always so hard?

*更新IV *

好了,上面的问题是,要求类有指回用户导航器 - 这解释了为什么上述方法指示类型为。用户_ [...] 并意味着我不仅需要做出向下的依赖序列化的,而且所有的路径回向上!然而,已经做了我成功地克隆对象,但现在我又回到了这个问题我原来发帖:

ok, so the problem above is that the Claim class has a navigator that points back to User - which explains why the above method indicates the type to be .User_[...] and implies I need to not only make the downward dependencies serializable, but also all of the paths back up! However, having done that I successfully clone the object but I'm now back to the issue in my original posting:

System.InvalidOperationException was unhandled by user code
  Message=Conflicting changes to the role 'User' of the relationship 'EF.ClaimUser' have been detected.
  Source=System.Data.Entity
  StackTrace:
       at System.Data.Objects.DataClasses.RelatedEnd.IncludeEntity(IEntityWrapper wrappedEntity, Boolean addRelationshipAsUnchanged, Boolean doAttach)
       at System.Data.Objects.DataClasses.EntityCollection`1.Include(Boolean addRelationshipAsUnchanged, Boolean doAttach)
       at System.Data.Objects.DataClasses.RelationshipManager.AddRelatedEntitiesToObjectStateManager(Boolean doAttach)
       at System.Data.Objects.ObjectContext.AddObject(String entitySetName, Object entity)
       at System.Data.Entity.Internal.Linq.InternalSet`1.<>c__DisplayClass5.<Add>b__4()
       at System.Data.Entity.Internal.Linq.InternalSet`1.ActOnSet(Action action, EntityState newState, Object entity, String methodName)
       at System.Data.Entity.Internal.Linq.InternalSet`1.Add(Object entity)
       at System.Data.Entity.DbSet`1.Add(TEntity entity)
       at Skillscore.Web.Controllers.AuthController.Register(String Company, String GivenName, String Surname, String Title, String Department) in C:\Users\.\Documents\Visual Studio 2010\Projects\.\Website\Controllers\AuthController.cs:line 138

男人。我需要在头一个洞。

man. I need a hole in the head.

*更新V *

我不知道,如果问题是代理或延迟加载,但想着这一点之后,似乎如果我通过序列的克隆,过去属于老对象所有ID的东西现在要属于新的一个。我也做了一个.remove()先旧的对象上,如果有立竿见影的效果,那么也许有什么东西在跟踪,不知道这件事。如果没有,那么在一个点上都会有两件事情在那里与相同的ID ...所以我开始朝着使用对象为initialisers克隆...

I don't know if the issue is the proxies or lazy loading, but after thinking about it a little, it seems that if I do a clone via serialisation, all the IDs for things that used to belong to the old object are now going to belong to the new one. I did do a .remove() first on the old object and if that has immediate effect then maybe there's something in the tracking that doesn't know about it. If it doesn't, then at one point there will be two things out there with the same ID... so I'm starting to lean towards @Jockey's idea of using object initialisers for the cloning...

推荐答案

如果你想获取该对象之前,序列化实体,您可以禁用代理的创建。如果你想它们序列化以及您还需要急于负荷导航属性。

If you want to serialize entities you can disable proxy creation before retrieving that object. You also need to eager load navigational properties if you want to serialize them as well.

要在EF 4.1禁用代理的创建

To disable proxy creation in EF 4.1

dbContext.Configuration.ProxyCreationEnabled = false;

在EF 4

objectContext.ContextOptions.ProxyCreationEnabled = false;

例如:

var users = context.Users.Include("Claims").Where(/**/);

这篇关于序列化类和EF动态代理 - 怎么样?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆