2013-09-26 2 views
2

Я, несомненно, пропустил что-то очевидное здесь, поэтому, возможно, коллективная сила Интернета может указать мне на это.Ошибка Breezejs при загрузке объекта со связанными данными

У меня есть первая структура базы данных кода, состоящая из пользователей, групп и таблицы GroupUsers для связывания двух (EF может обрабатывать n-n-отношения самостоятельно, но breezejs явно нуждается в таблице https://stackoverflow.com/a/13636530/249813).

Затем я пытаюсь загрузить пользователей через Breezejs у клиента. Это отлично работает, когда пользователь не является членом каких-либо групп, но не работает, когда имеет следующее сообщение.

object #<object> has no method getproperty 

Может ли кто-нибудь показать мне, где я иду не так?

База данных:

public class MyContext : DbContext 
{ 
    public DbSet<User> Users { get; set; } 
    public DbSet<Group> Groups { get; set; } 
    public DbSet<GroupUser> GroupUsers { get; set; } 
} 

public class User 
{ 
    [Key] 
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)] 
    public Guid Id { get; set; } 

    public string Name { get; set; } 

    [DataType(DataType.EmailAddress)] 
    public string Email { get; set; } 

    public bool IsActive { get; set; } 
    public bool IsAdmin { get; set; } 
    public virtual ICollection<GroupUser> Groups { get; set; } 
} 

public class Group 
{ 
    [Key] 
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)] 
    public Guid Id { get; set; } 

    public string Name { get; set; } 
    public virtual ICollection<GroupUser> Users { get; set; } 
} 

public class GroupUser 
{ 
    [Key] 
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)] 
    public Guid Id { get; set; } 

    [ForeignKey("User")] 
    public Guid UserId { get; set; } 

    [ForeignKey("Group")] 
    public Guid GroupId { get; set; } 

    public virtual Group Group { get; set; } 
    public virtual User User { get; set; } 
} 

Мусор

var serviceName = '/breeze/admin'; 
var manager = new breeze.EntityManager(serviceName); 
var query = breeze.EntityQuery.from('Users'); 

manager.executeQuery(query) 
    .then(function(data) { 
     //do something good 
    }) 
    .fail(function(error) { 
     //do something bad. 
    }); 

JSON производится с помощью контроллера Бриз API, когда пользователь не является членом группы (работает нормально)

[ 
    { 
     $id: "1", 
     $type: "System.Data.Entity.DynamicProxies.User_41E3B55B982835BEAAA863D9A28B60E1A07D42FBEB52862F05DCD4BAE3F6171C, EntityFrameworkDynamicProxies-MyBreezeTest", 
     Groups: [ ], 
     Id: "665b2a59-f1ae-41c6-8d6b-df758713db01", 
     Name: "Me", 
     Email: "[email protected]", 
     IsActive: true, 
     IsAdmin: true 
    } 
] 

JSON производства контроллером Breeze API, когда пользователь является членом группы (Fails)

[ 
    { 
     $id: "1", 
     $type: "System.Data.Entity.DynamicProxies.User_41E3B55B982835BEAAA863D9A28B60E1A07D42FBEB52862F05DCD4BAE3F6171C, EntityFrameworkDynamicProxies-MyBreezeTest", 
     Groups: [ 
      { 
       $id: "2", 
       $type: "System.Data.Entity.DynamicProxies.GroupUser_144E644846F6E074946B6DFE31A643AFBBDA0EF263BEBCAA9A6A12E67649A7CF, EntityFrameworkDynamicProxies-MyBreezeTest", 
       Group: { 
        $id: "3", 
        $type: "System.Data.Entity.DynamicProxies.Group_4EDDE8FACA0560ADBB390090E3A6A147D06867A4A693B111AECF35D2CE7E458C, EntityFrameworkDynamicProxies-MyBreezeTest", 
        Users: [ 
         { 
          $ref: "2" 
         } 
        ], 
        Id: "86365a48-6f45-4614-b0b0-8011ec0e0d77", 
        Name: "Test Group" 
       }, 
       User: { 
        $ref: "1" 
       }, 
       Id: "952faa7b-658d-4e12-8f18-dc9b0898d684", 
       UserId: "665b2a59-f1ae-41c6-8d6b-df758713db01", 
       GroupId: "86365a48-6f45-4614-b0b0-8011ec0e0d77" 
      } 
     ], 
     Id: "665b2a59-f1ae-41c6-8d6b-df758713db01", 
     Name: "Me", 
     Email: "[email protected]", 
     IsActive: true, 
     IsAdmin: true 
    } 
] 

Редактировать Для будущих читателей

ответ Margabit в ниже правильно идентифицирует проблему, однако для удобства, самый простой способ решить эту проблему, не делать этого в контроллере ветер:

var context = new MyContext(); 

, но вместо этого сделать это

var context = _myEFContextProvider.Context; 

С EFContex tProvider отключит создание прокси и ленивую загрузку на свой собственный экземпляр и позволит вам поддерживать виртуальный и избегать глобально отключать ленивую загрузку в конструкторе контекста.

ответ

3

Думаю, вы можете использовать Lazy Loading in EF. Вот почему у вас есть динамические прокси в свойствах навигации.

В Breeze документации говорится, что ленивая загрузка не вариант для Breeze:

отложенной загрузки

несколько раз мы упоминали о возможности , что существует связанный объект в удаленных но отсутствует в кэше . Свойства навигации Breeze возвращают только те объекты, которые находятся в кеше .

В некоторых системах свойство навигации автоматически извлекает связанные объекты из удаленного хранилища, если они еще не были в кеше .Этот процесс часто называют «ленивой загрузкой» или «отложенной загрузкой », потому что связанные объекты загружаются только в кеш при запросе .

Ленивая нагрузка не является вариантом бриза. Бриз ожидает, что вы должны явно загрузить . Вы можете загрузить их напрямую либо по адресу , запрашивая их, либо косвенно, как побочный продукт другого запроса.

Так что вам нужно будет отключить Ленивый Load и загрузите Groups и Type объекты в явном виде.

Вы можете удалить отложенную загрузку путем удаления virtual в свойствах навигации (только те, которые вы не хотите, чтобы загрузить) или глобально, установив в контексте:

this.Configuration.LazyLoadingEnabled = false; 

Вы можете включать навигационные свойства по:

[HttpGet] 
public IQueryable<YourEntity> Orders() { 
    return _contextProvider.Context.YourEntities.Include("Groups").Include("Type"); 
} 

Или загрузив их в запросе из JavaScript:

EntityQuery.from("YourEntities") 
.expand("Groups", "Type"); 

Ссылки:

EFContextProvider

Navigation Properties

+0

Я попытался отключить отложенную загрузку через конфигурацию после чтения, что очень часть документации и по-прежнему не работает. Однако либо полное отключение создания прокси, либо удаление виртуальных объектов в навигационных свойствах прелести. Спасибо. – JamesT

+0

Другое, что творит чудеса, использует EFContextProvider.Context вместо создания нового. Что кажется удивительно очевидным в холодном суровом свете утра. Предположительно, поскольку EFContextProvider правильно настраивает – JamesT

Смежные вопросы