DbContext создает исключение по запросу при доступе через интерфейс - PullRequest
6 голосов
/ 20 января 2012

Я создал интерфейс, который реализует мой класс DbContext, это позволяет мне создавать поддельный контекст БД для модульного тестирования.До сих пор это работает хорошо для всех моих запросов 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())

, тогда запрос выполняется отлично.

Так что мои вопросы:

  1. Почему он работает через DemoContext, а не IDemoContext?
  2. Как изменить IDemoContext, чтобы этот запрос работал через интерфейс?

Ответы [ 2 ]

5 голосов
/ 20 января 2012

Попробуйте заменить 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();
    }
0 голосов
/ 20 января 2012

Нашел решение, хитрость была в том, чтобы включить 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();
    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...