none
WCF An existing connection was forcibly closed by the remote host error RRS feed

  • Question

  • Hi,

    I host my service using Entity Framwork but  I have the problem  below ?

    The service host does not accept virtual List

     

       [DataContract]

        public class Training
        {
            [DataMember]
            public Guid TrainingID { get; set; }
    
            [DataMember]
            [Required(ErrorMessage = "An Album Title is required")]
            [StringLength(500)]
            public string Libelle { get; set; }
    
            #region - RelationShips
            [DataMember]
            public virtual List<ProductTraining> ProductTrainings { get; set;      
    
            #endregion
    }
    

     

    The errors message is 

     

    An existing connection was forcibly closed by the remote host

     

    But  it works if I remove virtual  keyword 

     

     public virtual List<ProductTraining> ProductTrainings { get; set;      

     


    mardi 17 janvier 2012 10:23

Réponses

  • Hm... Probablement quelque chose qui m'échappe, mais bon.

    J'utilise EF CODE FIRST , donc l'appel de TrainingService.GetByID(id)   me retourne directement le training concerné avec toutes ses associations.

    Peux tu essayer de remplacer ta méthode (dans Training Service)

     

     public Training GetByID(Guid TrainingId)
    {
          return _Training.GetByID(TrainingId);
    }

     

    par 

     

    public Training GetByID(Guid TrainingId)
    {
         return _Training.Get(t => t.Id == TrainingId, null, "ProductTrainings").FirstOrDefault();
    }

    Ceci afin que ton appel demande EXPLICITEMENT le chargement de ta collection ProductTrainings...
    Sébastien Putier
    Consultant - Formateur technologies Microsoft
    Blog : http://sputier.wordpress.com
    MCTS Développement d'application Windows 4.0
    Si un post vous parait utile, n'oubliez pas de le marquer comme utile. S'il répond à votre question, n'oubliez pas de le marquer comme réponse.
    • Marqué comme réponse gophette jeudi 19 janvier 2012 21:48
    jeudi 19 janvier 2012 13:52

Toutes les réponses

  • Bonjour, 

    Tout d'abord, étant sur un forum français, il serait souhaitable que ta question soit posée en français.

     

    Après quelques recherches sur le net, j'ai trouvé une solution potentielle : 

    Peux-tu essayer le code suivant STP ?

     

    var monObjectContext = new ObjectContext(); //Mets ici le type de ton contexte, évidemment
    
    monObjectContext.ContextOptions.ProxyCreationEnabled = false;

     

     

    Si ProxyCreationEnabled == true, alors EntityFramework encapsule ton objet Training dans une classe proxy pour suivre les modifications faites à ton objet. Or :

    - Comme tu travailles en mode déconnecté (Connexion => récupération => Déconnexion), ces proxies ne te sont pas utiles.

    - Ces proxies ne sont pas sérialisables, donc WCF crie fort quand il essaie de les sérialiser.

     

    Cordialement,

    Sébastien


    Sébastien Putier
    Consultant - Formateur technologies Microsoft
    Blog : http://sputier.wordpress.com
    MCTS Développement d'application Windows 4.0
    mardi 17 janvier 2012 11:01
  • Merci,

    Mon context ne contient pas l'objet  ContextOptions,

    J'utilise EF Code First

     

     public class StoreContext : DbContext
        {
            public DbSet<Category> Categories { get; set; }
            public DbSet<CategoryProduct> CategoryProducts { get; set; }
        }
    


    • Marqué comme réponse gophette mardi 17 janvier 2012 19:28
    • Non marqué comme réponse gophette mardi 17 janvier 2012 19:28
    mardi 17 janvier 2012 11:20
  • Pour Code First, il faut utiliser : 

     

    var monDbContext = new DbContext(); //Mets ici le type de ton contexte, évidemment
    
    monDbContext.DbContextConfiguration.ProxyCreationEnabled = false;

    EDIT : Une erreur s'est glissée insidieusement dans mon code. Il faut lire :
    monDbContext.Configuration.ProxyCreationEnabled = false;
    
    Cordialement,
    Sébastien

     


    Sébastien Putier
    Consultant - Formateur technologies Microsoft
    Blog : http://sputier.wordpress.com
    MCTS Développement d'application Windows 4.0
    • Marqué comme réponse gophette mardi 17 janvier 2012 19:28
    • Modifié Sébastien Putier mardi 17 janvier 2012 19:55
    • Non marqué comme réponse gophette mercredi 18 janvier 2012 18:37
    mardi 17 janvier 2012 12:07
  • Merci,

    il me semble que DbContext ne contient pas  DbContextConfiguration et pourtant ouie car en allant a la definition de la classe DbContex, je vois que cette methode existe bel et bien.

    Je pense aussi que c'est aussi  normal puisque StoreContext hérite de  DbContext.

    Voici mon code mais cela ne compile pas :

    public class StoreContext : DbContext
    {
            public DbSet<Category> Categories { get; set; }
            public DbSet<CategoryProduct> CategoryProducts { get; set; }
    }
    
    


    Mon Data Repository :

      public class DataRepository<T> : IDataRepository<T> where T : class
        {
            public  StoreContext _context ;
            internal DbSet<T> _dbSet;
    
            public DataRepository()
                : this(new StoreContext())
                {
                    _context = new DbContext("");
                    this._dbSet = _context.Set<T>();
                }
    
            public DataRepository(StoreContext context)
            {
               context.DbContextConfiguration.ProxyCreationEnabled = false;
    
                 _context = context;
                 _context.Database.Connection.ConnectionString = @"Data Source=TOC\SERVER_R2;Initial Catalog=STORES;Integrated Security=True  ;MultipleActiveResultSets=True;Application Name=EntityFrameworkMUE";
                this._dbSet = context.Set<T>();
            }
    
            public IQueryable<T> Fetch()
            {
                return _dbSet;
            }
    
    
            public IEnumerable<T> GetAll()
            {
                return GetQuery().AsEnumerable();
            }
    
            private List<T> GetQuery()
            {
                return _dbSet.ToList<T>();
            }
    }
    

    Mon service :

     

     public class CategoryService : ICategoryService, IDisposable
        {
            private DataRepository<Category> _Category;
    
            public CategoryService()
            {
                if (this._Category == null)
                {
                    this._Category = new DataRepository<Category>();
                }
            }
           
            
            public Category GetByID(Guid CategoryId)
            {
                return _Category.GetByID(CategoryId);
            }
    }
    


    mardi 17 janvier 2012 19:18
  • en fait , 

     public virtual List<ProductTraining> ProductTrainings { get; set; }
    J'ai pas d'erreur d'execution mais List<ProductTraining> vaut toujours null ;

     


    • Modifié gophette mercredi 18 janvier 2012 18:39
    mardi 17 janvier 2012 19:27
  • C'est probablement lié à la notion de Lazy Loading. Tu peux aussi le désactiver en utilisant : 

     

    monDbContext.Configuration.LazyLoadingEnabled = false;

     

    Le Lazy Loading permet de ne charger des éléments liés que lorsque tu en as besoin. Or tu travailles en mode déconnecté, donc ce chargement ne se fait pas.

    Désactiver le Lazy Loading devrait donc permettre de charger automatiquement tes éléments ProductTraining en même temps que toutes les autres propriétés de ta classe Training.


    Sébastien Putier
    Consultant - Formateur technologies Microsoft
    Blog : http://sputier.wordpress.com
    MCTS Développement d'application Windows 4.0
    jeudi 19 janvier 2012 08:40
  • Merci

    C'est toujours null,

    Je pense que je vais écrire une requête pour aller chercher les ProductTraining  du produits en cours.

    jeudi 19 janvier 2012 11:31
  • Serait-il possible que tu fournisses le code qui récupère l'objet Training, stp ?

    Je pense que je vais écrire une requête pour aller chercher les ProductTraining  du produits en cours.

    C'est aussi une solution. 
    Sébastien Putier
    Consultant - Formateur technologies Microsoft
    Blog : http://sputier.wordpress.com
    MCTS Développement d'application Windows 4.0
    Si un post vous parait utile, n'oubliez pas de le marquer comme utile. S'il répond à votre question, n'oubliez pas de le marquer comme réponse.
    jeudi 19 janvier 2012 11:40
  • Mon DataRepository

    public class DataRepository<T> : IDataRepository<T> where T : class
        {
            public StoreContext _context ;
            internal DbSet<T> _dbSet;
    
            public DataRepository()
                : this(new StoreContext())
                {
                    
                    this._dbSet = _context.Set<T>();
                }
    
            public DataRepository(StoreContext context)
            {
                /* Enable WCF call */
                context.Configuration.LazyLoadingEnabled = false;
                context.Configuration.ProxyCreationEnabled = false;
    
                /* End Enable WCF call */
               
                 _context = context;
                 _context.Database.Connection.ConnectionString = @"Data Source=TOCANE\SERVER_R2;Initial Catalog=STORES;Integrated Security=True  ;MultipleActiveResultSets=True;Application Name=EntityFrameworkMUE";
                this._dbSet = context.Set<T>();
            }
    
            public IQueryable<T> Fetch()
            {
                return _dbSet;
            }
    
    
            public IEnumerable<T> GetAll()
            {
                return GetQuery().AsEnumerable();
            }
    
            private List<T> GetQuery()
            {
                return _dbSet.ToList<T>();
            }
    
            public virtual IEnumerable<T> Get(
                                              Expression<Func<T, bool>> filter = null,
                                              Func<IQueryable<T>,
                                              IOrderedQueryable<T>> orderBy = null,
                                              string includeProperties = "")
            {
                IQueryable<T> query = _dbSet;
    
                if (filter != null)
                {
                    query = query.Where(filter);
                }
    
                foreach (var includeProperty in includeProperties.Split
                    (new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries))
                {
                    query = query.Include(includeProperty);
                }
    
                if (orderBy != null)
                {
                    return orderBy(query).ToList();
                }
                else
                {
                    return query.ToList();
                }
            }
    
            public virtual IEnumerable<T> GetWithRawSql(string query, params object[] parameters)
            {
                return _dbSet.SqlQuery(query, parameters).ToList();
            }
    
            public IEnumerable<T> Find(Func<T, bool> predicate)
            {
                return _dbSet.Where<T>(predicate);
            }
    
            public T Single(Func<T, bool> predicate)
            {
                try
                {
                    return _dbSet.Single<T>(predicate);
                }
                catch
                {
                    return null;
                }
            }
    
            public T GetByID(object id)
            {
                try
                {
                    return _dbSet.Find(id);
                }
                catch (Exception ex) 
                {
                    return null;
                }
            }
    
            public T First(Func<T, bool> predicate)
            {
                return _dbSet.First<T>(predicate);
            }
    
            public void Delete(T entity)
            {
                if (entity == null)
                {
                    throw new ArgumentNullException("entity");
                }
    
                _dbSet.Remove(entity);
            }
    
            public void Delete(Func<T, bool> predicate)
            {
                IEnumerable<T> records = from x in _dbSet.Where<T>(predicate) select x;
    
                foreach (T record in records)
                {
                    _dbSet.Remove(record);
                }
            }
    
            public void Add(T entity)
            {
                if (entity == null)
                {
                    throw new ArgumentNullException("entity");
                }
    
                _dbSet.Add(entity);
                SaveChanges();
            }
    
            public void Attach(T entity)
            {
                try
                {
                    _dbSet.Attach(entity);
                }
                catch (DbEntityValidationException dbEx)
                {
                    foreach (var validationErrors in dbEx.EntityValidationErrors)
                    {
                        foreach (var validationError in validationErrors.ValidationErrors)
                        {
                            string error = string.Format("Property: {0} Error: {1}", validationError.PropertyName, validationError.ErrorMessage);
                        }
                    }
                }
            }
    
    
            public void SaveChanges()
            {
                try
                {
                    _context.SaveChanges();
                }
                catch (DbEntityValidationException dbEx)
                {
                    string error = string.Empty;
                    foreach (var validationErrors in dbEx.EntityValidationErrors)
                    {
                        foreach (var validationError in validationErrors.ValidationErrors)
                        {
                            error = string.Format("Property: {0} Error: {1}", validationError.PropertyName, validationError.ErrorMessage);
                        }
                    }
    
                    throw new Exception(error, dbEx);
                }
                catch (Exception ex)
                {
                    throw new Exception(ex.Message,ex);
                }
            }
    
            public void Dispose()
            {
                Dispose(true);
                GC.SuppressFinalize(this);
            }
    
            protected virtual void Dispose(bool disposing)
            {
                if (disposing)
                {
                    if (_context != null)
                    {
                        _context.Dispose();
                        _context = null;
                    }
                }
            }
    
    
          
        }
    


    Ma Mon Service TrainingService

    public class TrainingService : ITrainingService, IDisposable
        {
            private DataRepository<Training> _Training;
            
            public TrainingService()
            {
                if (this._Training == null)
                {
                    this._Training = new DataRepository<Training>();
                }
            }
    
            public IEnumerable<Training> getList()
            {
                return _Training.GetAll();
            }
    
            public void Add(Training Training)
            {
                _Training.Add(Training);
            }
    
            public Training GetByID(Guid TrainingId)
            {
                return _Training.GetByID(TrainingId);
            }
    
            public void Save()
            {
                _Training.SaveChanges();
            }
    
           
            
        }
    


    Mon Contexte

    public class SofwareStoreContext : DbContext
    {
        public DbSet<Category> Categories { get; set; }
        public DbSet<Training> Trainings { get; set; }
        public DbSet<ProductTraining> ProductTrainings { get; set; }
    }
    


    J'utilise EF CODE FIRST , donc l'appel de TrainingService.GetByID(id)   me retourne directement le training concerné avec toutes ses associations.

    Cela fonctionne lors que je désactive l'appel de WCF

    • Marqué comme réponse gophette jeudi 19 janvier 2012 21:48
    • Non marqué comme réponse gophette jeudi 19 janvier 2012 21:48
    jeudi 19 janvier 2012 12:28
  • Hm... Probablement quelque chose qui m'échappe, mais bon.

    J'utilise EF CODE FIRST , donc l'appel de TrainingService.GetByID(id)   me retourne directement le training concerné avec toutes ses associations.

    Peux tu essayer de remplacer ta méthode (dans Training Service)

     

     public Training GetByID(Guid TrainingId)
    {
          return _Training.GetByID(TrainingId);
    }

     

    par 

     

    public Training GetByID(Guid TrainingId)
    {
         return _Training.Get(t => t.Id == TrainingId, null, "ProductTrainings").FirstOrDefault();
    }

    Ceci afin que ton appel demande EXPLICITEMENT le chargement de ta collection ProductTrainings...
    Sébastien Putier
    Consultant - Formateur technologies Microsoft
    Blog : http://sputier.wordpress.com
    MCTS Développement d'application Windows 4.0
    Si un post vous parait utile, n'oubliez pas de le marquer comme utile. S'il répond à votre question, n'oubliez pas de le marquer comme réponse.
    • Marqué comme réponse gophette jeudi 19 janvier 2012 21:48
    jeudi 19 janvier 2012 13:52
  • Ok,

    ça fonctionne.

    Merci beaucoup, monsieur l'Expert

    jeudi 19 janvier 2012 21:49