DbContext throws an exception on request when accessing through the interface

I created an interface that implements my DbContext class, this allows me to create a fake db context for unit testing. This works well for all of my LINQ queries, as long as I get the following exception:

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

Executing a LINQ query through the interface raises the above exception, however, when executing the same query directly in my DBContext, the query works 100%. Here is a description of the interface and related demo codes:

  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; } } 

Each member potentially belongs to one primary team and, possibly, to many secondary teams. The following demo code throws an exception:

 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(); } 

If I changed the first line to:

 using (DemoContext dbi = new DemoContext()) 

then the request is executed perfectly.

So my questions are:

  • Why does this work through DemoContext and not IDemoContext?
  • How do I change IDemoContext so that this request works through an interface?
+6
source share
2 answers

Try replacing dbi.Members with a local variable in the request.

  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(); } 
+5
source

Found a solution, the trick was to include the SecondaryTeams request in the request:

  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(); } 
0
source

Source: https://habr.com/ru/post/906442/


All Articles