2012-01-19 14 views
6

He creado una interfaz que implementa mi clase DbContext, esto me permite crear un contexto falso de base de datos para pruebas unitarias. Esto funciona bien para toda mi LINQ consulta hasta ahora, pero uno, donde consigo la siguiente excepción:DbContext arroja una excepción en la consulta cuando se accede a través de la interfaz

Unable to create a constant value of type 'DemoApp.Member'. Only primitive types ('such as Int32, String, and Guid') are supported in this context. 

Ejecutar la consulta LINQ a través de la interfaz produce la excepción anteriormente, sin embargo al ejecutar la misma consulta exacta directamente en mi DBContext la consulta funciona al 100%. Aquí es la interfaz y definiciones de los códigos de demostración relacionados:

interface IDemoContext : IDisposable 
{ 
    IDbSet<Member> Members { get; set; } 
    IDbSet<Team> Teams { get; set; } 
} 

public partial class DemoContext : DbContext, IDemoContext 
{ 
    public DemoContext() : base("name=DemoContext"){} 

    public IDbSet<Member> Members { get; set; } 
    public IDbSet<Team> Teams { get; set; } 
} 

public partial class Member 
{ 
    public Member() 
    { 
     this.SecondaryTeams = new HashSet<Team>(); 
    } 

    public int ID { get; set; } 
    public string Name { get; set; } 
    public int? PrimaryTeamID { get; set; } 

    public virtual Team PrimaryTeam { get; set; } 
    public virtual ICollection<Team> SecondaryTeams { get; set; } 
} 

public partial class Team 
{ 
    public Team() 
    { 
     this.PrimaryMembers = new HashSet<Member>(); 
     this.SecondaryMembers = new HashSet<Member>(); 
    } 

    public int ID { get; set; } 
    public string Name { get; set; } 

    public virtual ICollection<Member> PrimaryMembers { get; set; } 
    public virtual ICollection<Member> SecondaryMembers { get; set; } 
} 

Cada miembro potencialmente pertenece a un solo equipo primario y, opcionalmente, muchos equipos secundarios. El siguiente código de demostración lanza la excepción:

using (IDemoContext dbi = new DemoContext()) 
     { 
      var members = 
       (from member in dbi.Members 
       select new 
       { 
        Name = member.Name, 
        Team = member.PrimaryTeam.Name, 
        SecondaryTeams = from secondaryTeam in member.SecondaryTeams 
         join primaryMember in dbi.Members 
         on secondaryTeam.ID equals primaryMember.PrimaryTeamID 
         into secondaryTeamMembers 
         select new 
         { 
          Name = secondaryTeam.Name, 
          Count = secondaryTeamMembers.Count() 
         } 
       }).ToList(); 
     } 

Si cambio de la primera línea a:

using (DemoContext dbi = new DemoContext()) 

entonces la consulta se ejecuta a la perfección.

Así que mis preguntas son:

  1. ¿Por qué funciona a través DemoContext y no IDemoContext?
  2. ¿Cómo cambio IDemoContext para que esta consulta funcione a través de la interfaz?

Respuesta

5

Intente reemplazar dbi.Members con una variable local en la consulta.

using (IDemoContext dbi = new DemoContext()) 
    { 
     IQueryable<Member> memberSet = dbi.Members; 

     var members = 
      (from member in memberSet 
      select new 
      { 
       Name = member.Name, 
       Team = member.PrimaryTeam.Name, 
       SecondaryTeams = from secondaryTeam in member.SecondaryTeams 
        join primaryMember in memberSet 
        on secondaryTeam.ID equals primaryMember.PrimaryTeamID 
        into secondaryTeamMembers 
        select new 
        { 
         Name = secondaryTeam.Name, 
         Count = secondaryTeamMembers.Count() 
        } 
      }).ToList(); 
    } 
+0

Con este cambio ahora lanza una nueva excepción: objeto de tipo 'System.Data.Objects.ObjectQuery'1 [DemoApp.Member] 'no se puede convertir a tipo' System.Data.Entity.IDbSet'1 [DemoApp.Member] '. Esta excepción se aplica tanto a IDemoContext como a DemoContext. – Beyers

+0

@Beyers Básicamente 'memberset' tiene que ser del tipo' IQueryable '. Respuesta actualizada – Eranga

+0

Impresionante, esto funciona al 100% y es una solución mejor que mi solución con dbi.Members.Include (i => i.SecondaryTeams). Todavía estoy interesado en saber exactamente por qué falla a través de la interfaz y no a través de DBContext. – Beyers

0

encontrado la solución, el truco era incluir SecondaryTeams en la consulta:

using (IDemoContext dbi = new DemoContext()) 
    { 
    var memberset = dbi.Members.Include(i => i.SecondaryTeams); 
    var members = 
     (from member in memberset 
     select new 
     { 
      Name = member.Name, 
      Team = member.PrimaryTeam.Name, 
      SecondaryTeams = from secondaryTeam in member.SecondaryTeams 
           join primaryMember in memberset 
       on secondaryTeam.ID equals primaryMember.PrimaryTeamID 
       into secondaryTeamMembers 
       select new 
       { 
        Name = secondaryTeam.Name, 
        Count = secondaryTeamMembers.Count() 
       } 
     }).ToList(); 
    } 
Cuestiones relacionadas