装载有相关的数据实体时Breezejs错误 [英] Breezejs error when loading an entity with related data

查看:175
本文介绍了装载有相关的数据实体时Breezejs错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我毫不怀疑缺少明显的东西在这里所以也许互联网的集体的力量能指出来给我。

I'm no doubt missing something obvious here so perhaps the collective power of the internet can point it out to me.

我有一个code第一数据库结构,包括用户,组和一个GroupUsers表链接两个(EF可以处理N-N关系本身,而是需要breezejs表明确<一个href=\"http://stackoverflow.com/a/13636530/249813\">http://stackoverflow.com/a/13636530/249813).

I have a code first database structure, consisting of Users, Groups and a GroupUsers table to link the two (EF can handle n-n relationships itself but breezejs needs the table explicitly http://stackoverflow.com/a/13636530/249813).

我想,然后在客户端通过Breezejs加载用户。这工作得很好,当用户不属于任何组的成员,但当它们与下面的消息会失败。

I'm then trying to load users via Breezejs at the client. This works fine when a user is not a member of any groups, but fails when they are with the following message.

object #<object> has no method getproperty

谁能告诉我,我要去哪里错了?

Could anyone show me where I'm going wrong?

数据库:

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

的JavaScript

Javascript

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微风控制器产生时,用户不是一个组(正常工作)

JSON produced by Breeze API controller when user isn't a member of a group (Works fine)

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

通过JSON API微风控制器时产生的用户是一个组的成员(失败)

JSON produced by Breeze API controller when user IS a member of a group (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: "me@example.com",
        IsActive: true,
        IsAdmin: true
    }
]

修改对于未来的读者

下面正确Margabit的回答标识问题,但是为了便于参考解决这个招展控制器无法做到这一点最简单的方法:

Margabit's answer below correctly identifies the problem, however for ease of reference the simplest way to solve this is not do this in the breeze controller:

var context = new MyContext();

而是做到这一点。

but instead do this

var context = _myEFContextProvider.Context;

由于EFContextProvider将在它自己的实例禁用代理的创建和延迟加载,让您保持您的虚拟并在全球范围避免在上下文构造禁用延迟加载。

Since EFContextProvider will disable proxy creation and lazy loading on it's own instance and allow you to keep your virtual and avoid globally disabling lazy loading in the context constructor.

推荐答案

我想你可能在EF使用延迟加载。这就是为什么你在导航性能有动态代理。

I think you might be using Lazy Loading in EF. This is why you have Dynamic Proxies in the navigation properties.

在微风文档中说,延迟加载不是微风一个选项:

In Breeze documentation says that Lazy Loading is not an option for Breeze:

延迟加载

在多个场合,我们已经提到的可能性
  一个相关的实体存在于远程存储,但不是presently在
  缓存。微风导航属性只返回了在实体
  缓存。

On several occasions we’ve alluded to the possibility that a related entity exists in remote storage but is not presently in cache. Breeze navigation properties only return entities that are in cache.

在一些系统中,导航属性会自动获取
  从远程存储相关的实体,如果他们尚未在
  缓存。这个过程通常被称为懒加载或延期
  装载,因为相关实体只加载到缓存中,当
  请求。

In some systems, a navigation property would automatically fetch the related entities from remote storage if they were not already in cache. This process is often called "lazy loading" or "deferred loading" because related entities are only loaded into cache when requested.

延迟加载不是一个微风的选择。微风希望你加载
  相关实体明确。您可以直接加载它们
  查询他们或间接作为另一个查询的副产品。

Lazy loading is not a Breeze option. Breeze expects you to load related entities explicitly. You can load them either directly by querying for them or indirectly as a byproduct of another query.

所以,你需要禁用延迟加载,并明确载入键入实体。

So you will need to disable Lazy Load and load the Groups and Type entities explicitly.

您可以通过删除删除延迟加载的虚拟在导航性能(只是你不希望加载的那些),或通过全球的背景下设置

You can remove the Lazy Loading by removing the virtual in the navigation properties (just the ones that you don't want to load) or globally by setting in the context:

  this.Configuration.LazyLoadingEnabled = false; 

您可以通过包括导航属性:

You can include the navigation properties by:

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

或从JavaScript在查询加载它们:

Or by loading them in the Query from JavaScript:

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

参考文献:

EFContextProvider

导航属性

这篇关于装载有相关的数据实体时Breezejs错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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