我创建了一个我的DbContext类实现的接口,这使我能够为单元测试创建一个假的db上下文。到目前为止,这对我的所有LINQ查询都很有效,但是我得到以下异常:
Unable to create a constant value of type 'DemoApp.Member'. Only primitive types ('such as Int32, String, and Guid') are supported in this context.
通过接口执行LINQ查询会引发上述异常,但是当直接在我的DBContext上执行完全相同的查询时,查询将100%正常工作。这是接口和相关的演示代码定义:
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; }
}
每个成员可能属于一个主要团队,也可能属于多个辅助团队。以下演示代码抛出异常:
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();
}
如果我将第一行更改为:
using (DemoContext dbi = new DemoContext())
然后查询完美执行。
所以我的问题是:
答案 0 :(得分:5)
尝试用查询中的局部变量替换dbi.Members
。
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();
}
答案 1 :(得分:0)
找到解决方案,诀窍是在查询中包含SecondaryTeams:
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();
}