1

I am working on a project where we use WCF and Entity Framework. Because WCF wouldn't work with dynamic proxies, taken from here, I have put this line in the constructor of my context class:

public CarBatteryEntities() : base("name=CarBatteryEntities")
{
    base.Configuration.ProxyCreationEnabled = false;
}

WCF works, however my linq queries wouldn't return their associations.

This is my code:

List<Edge> edges = edgeRepository.GetBatteryCenterEdges("cityname").ToList();
foreach(var e in edges)
    Console.WriteLine(e);

Class Edge has 3 main variables - BatteryStation, BatteryStation and distance. It is an auto-generated class from the ET, both BatteryStation are connections to the other table.

If I use ProxyCreationEnabled as true everything works as a charm.

If I use ProxyCreationEnabled as false only distance would be returned correctly and both objects (BatteryStation and BatteryStation1) will be null.

Any suggestions?

public IList<Edge> GetBatteryCenterEdges(string name)
{
   var query = context.Edge
                      .Where(edge => edge.BatteryStation.name.Equals(name) 
                                  || edge.BatteryStation1.name.Equals(name))
                      .AsEnumerable()
                      .SelectMany(edge => new[] { 
                          edge, 
                          new Edge() { 
                              BatteryStation = edge.BatteryStation1, 
                              BatteryStation1 = edge.BatteryStation, 
                              distance = edge.distance 
                          } 
                      });

   return query.ToList();
}
Community
  • 1
  • 1
Nikola
  • 2,093
  • 3
  • 22
  • 43

3 Answers3

1

Since you've turned off proxies, you probably need to load the associations with Include().

joelmdev
  • 11,083
  • 10
  • 65
  • 89
1

Use Include() to perform eager loading:

using System.Data.Entity; // for Include extension method.

var results = ctx.Edges
    .Include(e => e.BatteryStation)
    .Include(e => e.BatteryStation1)
    .ToList();

Or perform explicit loading on each entity:

var results = ctx.Edges.ToList();

foreach(var e in results)
{
    ctx.Entry(e).Reference(x => x.BatteryStation).Load();
    ctx.Entry(e).Reference(x => x.BatteryStation1).Load();
}
Cory Nelson
  • 29,236
  • 5
  • 72
  • 110
  • On `Include(e => e.BatteryStation)` it returns an error which says "cannot convert lambda expression to type string – Nikola Dec 17 '13 at 17:15
  • It's an extension method in System.Data.Entity. This version is preferred over the one which takes a string, as it enables refactoring and will result in a compile-time error if one of those properties is missing. Answer updated. – Cory Nelson Dec 17 '13 at 17:19
0

You can do it as an extend method as follows .It is generic method to include any entities which is having relationship,and you can also do the same for any N number of includes by using an expression which returns the navigation properties to be with eager loaded.

public IQueryable<TEntity> GetAllIncluding(params Expression<Func<TEntity, object>>[] includeProperties) 
{
   IQueryable<TEntity> queryable = GetAll();
   foreach (Expression<Func<TEntity, object>> includeProperty in includeProperties) 
   {
      queryable = queryable.Include<TEntity, object>(includeProperty);
   }

   return queryable;
}
Thilina H
  • 5,754
  • 6
  • 26
  • 56