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:
- ¿Por qué funciona a través DemoContext y no IDemoContext?
- ¿Cómo cambio IDemoContext para que esta consulta funcione a través de la interfaz?
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
@Beyers Básicamente 'memberset' tiene que ser del tipo' IQueryable '. Respuesta actualizada –
Eranga
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