DbContext throws exception on query when accessed through interface

我的未来我决定 提交于 2019-12-09 17:58:30

问题


I have created an interface that my DbContext class implements, this enables me to create a fake db context for unit testing. This works well for all my LINQ queries so far but one, where 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 the LINQ query through the interface throws the above exception, however when executing the exact same query directly on my DBContext the query works 100%. Here is the interface and related demo code definitions:

    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 a single primary team, and optionally many secondary teams. The following demo code throws the 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 change the first line to:

using (DemoContext dbi = new DemoContext())

then the query executes perfectly.

So my questions are:

  1. Why does it work through DemoContext and not IDemoContext?
  2. How do I change IDemoContext so this query does work through the interface?

回答1:


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

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



回答2:


Found the solution, the trick was to Include SecondaryTeams in the query:

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


来源:https://stackoverflow.com/questions/8935094/dbcontext-throws-exception-on-query-when-accessed-through-interface

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!