通过界面访问时的DbContext抛出的查询异常 [英] DbContext throws exception on query when accessed through interface

查看:90
本文介绍了通过界面访问时的DbContext抛出的查询异常的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经创建了一个界面,我的DbContext类实现,这使我能够创建一个假的数据库环境进行单元测试。这非常适用于我所有的LINQ查询,到目前为止只有一个,在那里我得到了以下异常:

 无法创建类型的常量值'DemoApp.Member。只有原始类型('如的Int32,String和的Guid)在这方面的支持。
 

直接在我的DbContext执行完全相同的查询,但在通过接口执行LINQ查询抛出上述异常,查询的工作100%。这里是接口和相关的演示code定义:

 接口IDemoContext:IDisposable接口
{
    IDbSet<会员>成员{获得;组; }
    IDbSet<团队及GT;小组{获得;组; }
}

公共部分类DemoContext:的DbContext,IDemoContext
{
    公共DemoContext():基地(NAME = DemoContext){}

    公共IDbSet<会员>成员{获得;组; }
    公共IDbSet<团队及GT;小组{获得;组; }
}

公共部分类会员
{
    公有成员()
    {
        this.SecondaryTeams =新的HashSet<团队及GT;();
    }

    公众诠释ID {获得;组; }
    公共字符串名称{;组; }
    公众诠释? PrimaryTeamID {获得;组; }

    公共虚拟团队PrimaryTeam {获得;组; }
    公共虚拟的ICollection<团队及GT; SecondaryTeams {获得;组; }
}

公共部分类团队
{
    公开组()
    {
        this.PrimaryMembers =新的HashSet<会员>();
        this.SecondaryMembers =新的HashSet<会员>();
    }

    公众诠释ID {获得;组; }
    公共字符串名称{;组; }

    公共虚拟的ICollection<会员> PrimaryMembers {获得;组; }
    公共虚拟的ICollection<会员> SecondaryMembers {获得;组; }
}
 

每个成员可能属于一个初级的团队,和可选的许多中学队。下面的演示code抛出异常:

 使用(IDemoContext DBI =新DemoContext())
        {
            VAR成员=
                (会员在dbi.Members
                选择新
                {
                    名称= member.Name,
                    团队= member.PrimaryTeam.Name,
                    SecondaryTeams =从secondaryTeam在member.SecondaryTeams
                        加入primaryMember在dbi.Members
                        在secondaryTeam.ID等于primaryMember.PrimaryTeamID
                        进入secondaryTeamMembers
                        选择新
                        {
                            名称= secondaryTeam.Name,
                            数= secondaryTeamMembers.Count()
                        }
                })了ToList()。
        }
 

如果我的第一行更改为:

 使用(DemoContext DBI =新DemoContext())
 

那么查询执行完美。

所以,我的问题是:

  1. 为什么它通过DemoContext工作,而不是IDemoContext?
  2. 如何更改IDemoContext因此该查询不会通过该接口的工作?
解决方案

试着在查询一个局部变量替换 dbi.Members

 使用(IDemoContext DBI =新DemoContext())
    {
        IQueryable的<会员>成员集= dbi.Members;

        VAR成员=
            (从会员中成员集
            选择新
            {
                名称= member.Name,
                团队= member.PrimaryTeam.Name,
                SecondaryTeams =从secondaryTeam在member.SecondaryTeams
                    加入primaryMember的成员集
                    在secondaryTeam.ID等于primaryMember.PrimaryTeamID
                    进入secondaryTeamMembers
                    选择新
                    {
                        名称= secondaryTeam.Name,
                        数= secondaryTeamMembers.Count()
                    }
            })了ToList()。
    }
 

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?

解决方案

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

这篇关于通过界面访问时的DbContext抛出的查询异常的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆