2010-09-24 14 views
2

J'ai créé des classes POCO avec T4 Templates pour EF 4.0 et généré des simulacres pour Context. Tout était génial, mais je n'aime pas initialiser même une petite Mock-DB en code C#, donc j'ai créé quelques fonctions qui génèrent Mock-DB à partir de DB réel et je voulais sérialiser cet objet et l'utiliser plus tard dans certaines unités Tests ...Peut sérialiser, mais ne peut pas désérialiser?

La sérialisation XML échoue, j'ai donc essayé la sérialisation binaire et la sérialisation, mais la désérialisation a échoué.

Le désérialiseur ne trouve pas d'assemblage "EntityFrameworkDynamicProxies-". Comment puis-je désérialiser une telle chose (DynamicProxy?) ...

+0

Est-sérialiseur dans un séparé assemblée? – ChristopheD

+0

Vous voulez dire différent avec les classes POCO? Serializer est dans les classes TestProject et Poco et les mocks générés sont dans un projet séparé avec des modèles seulement, donc oui ils sont dans des assemblages séparés. – Simon

Répondre

1

Les proxys dynamiques n'existent que sur demande, donc les mauvais choix pour la sérialisation sont possibles. Qu'est-ce que nous l'erreur avec XML? En fin de compte, je pense que votre meilleure option ici est d'utiliser une couche DTO, mais que pourrait aussi également sérialiser avec d'autres sérialiseurs. Par exemple avez-vous essayé DataConttactSerializer, qui peut être en mesure de faire face? J'ai ajouté le support de proxy à mon propre serializer mais je n'ai pas encore essayé avec ef4.

+0

Je ne sais pas, vaut-il mon effort.Je veux juste créer une petite partie de la grande DB, qui peut être facilement utilisé dans les tests unitaires. Il devrait être statique, donc je pensais que la sérialisation serait la meilleure et la plus rapide. Je n'ai pas essayé DataContractSerializer, mais je pense aussi à d'autres possibilités ... Y a-t-il un moyen d'obtenir un objet réel? Qu'est-ce que je fais en ce moment est de traverser DB, point de départ est une entité, et je récupère toutes les dépendances en les ajoutant à MockContext (qui est basé sur List <>), donc lors de l'ajout d'objet à MockContext je pourrais sauter le proxy. C'est possible? – Simon

+0

Lors de la sérialisation via XML, j'ai reçu des erreurs XmlInclude. Sérialiseur trouver le type inattendu et je devrais ajouter XmlInclude aux types qui ne sont pas connus statiquement ... – Simon

+0

@Simon - oui, c'est ce que je * attendais *, mais je voulais être sûr. Je ne sais pas assez sur l'implémentation EF pour le savoir, mais c'est * possible * avec NHibernate, je pense que c'est possible. Mais vous devriez le google. DTO est plus simple ... –

1

Si vous créez d'abord votre instance de la classe à partir du contexte d'entité dans l'application, la désérialise, cela peut fonctionner pour vous. Donc, dans votre application qui est de désérialiser cela, essayez de faire quelque chose comme

context.YourSerializedObjectType.CreateObject(); où contexte est une instance de votre contexte d'objet entité.

J'ai eu un problème similaire, j'ai pu travailler autour (en partie) en faisant cela dans un mvc Application_Start

de l'application web

http://completedevelopment.blogspot.com/2010/09/aspnetmvcentity-framework-error-unable.html

lui donner un tourbillon.

1

j'ai réussi en mesure de résoudre ce problème en enregistrant un SerializationBinder personnalisé avec le BinaryFormatter: (EF6)

string file = "data.bin"; 
using (var ctx = new DataContext()) 
{ 
    BinaryFormatter bf = new BinaryFormatter(); 
    bf.Binder = new MyBinder(); 

    Entity e; 
    using (var s = File.OpenRead(file)) 
     e = (Entity)bf.Deserialize(s); 

    ctx.Entities.Add(e); 
    ctx.SaveChanges(); 

    File.Move(file, Path.Combine(archiveFolder, Path.GetFileName(file))); 
} 



class MyBinder : SerializationBinder 
{ 
    Dictionary<string, Type> types; 

    public MyBinder() 
    { 
     types = typeof(Entity).Assembly.GetTypes().Where(t => t.Namespace == "Foo.Model").ToDictionary(t => t.Name, t => t); 
    } 

    public override Type BindToType(string assemblyName, string typeName) 
    { 
     if (assemblyName.Contains("EntityFrameworkDynamicProxies-Foo")) 
     { 
      var type = typeName.Split('.').Last().Split('_').First(); 
      return types[type]; 
     } 

     var returnType = Type.GetType(String.Format("{0}, {1}", typeName, assemblyName)); 
     return returnType; 
    } 
} 
Questions connexes