gpt4 book ai didi

c# - EF 中的可序列化类和动态代理 - 怎么样?

转载 作者:IT王子 更新时间:2023-10-29 04:37:46 25 4
gpt4 key购买 nike

[a previous posting] ,我走上了必须克隆我的实体的道路。我尝试使用 [codeproject] 中的序列化方法来做到这一点.

因为这些类是由 Entity Framework 生成的,所以我在自定义 .cs 中单独标记它们,如下所示:

[Serializable]
public partial class Claims
{
}

但是,当检查时(在克隆方法中):

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

被击中,我得到错误:

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:

显然我的课Claims是可序列化的,EF 生成的动态代理不是......不知何故我的装饰没有流过。

这里有什么技巧?

* 更新一 *

更多上下文:我有一个类 User其中包含属性 Claims定义为 ICollection<Claim> .进行克隆时,传递的类型是集合,而不是 Claim - 这解释了为什么克隆者提示该类型不可序列化。所以现在的问题是:我如何制作 User.Claims可序列化,因为我无法装饰属性?

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

* 更新二 *

练习的重点是创建深拷贝。这是它的样子:

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必须是可序列化的,但不是出于上述原因。

* 更新三 *

好的,我改变了方法,像这样实现构造函数:

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() 的检查(上面的“if”行),但现在它在以下位置中断:

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

唉……凡事总是那么艰难吗?

* 更新 IV *

好的,所以上面的问题是 Claim类有一个导航器指向 User - 这解释了为什么上述方法将类型指示为 .User_[...]并暗示我不仅需要使向下依赖项可序列化,而且还需要备份所有路径!然而,完成后我成功地克隆了对象,但我现在回到我原来的帖子中的问题:

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

男人。我需要在头上打个洞。

* 更新 V *

我不知道是代理问题还是延迟加载问题,但稍微考虑了一下,似乎如果我通过序列化进行克隆,所有曾经属于旧对象的东西的ID现在将属于新的。我确实做了 .remove()首先在旧对象上,如果它立即生效,那么跟踪中可能有一些不知道它的东西。如果没有,那么在某一时刻会有两个具有相同 ID 的东西……所以我开始倾向于@Jockey 的使用对象初始化器进行克隆的想法……

最佳答案

如果您想序列化实体,您可以在检索该对象之前禁用代理创建。如果您还想序列化它们,您还需要预先加载导航属性。

在 EF 4.1 中禁用代理创建

dbContext.Configuration.ProxyCreationEnabled = false;

在 EF 4 中

objectContext.ContextOptions.ProxyCreationEnabled = false;

例如:

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

关于c# - EF 中的可序列化类和动态代理 - 怎么样?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7276507/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com