2

ここで明らかな何かが欠けていることは間違いないので、おそらくインターネットの集合的な力がそれを指摘してくれるでしょう。

ユーザー、グループ、および2つをリンクするGroupUsersテーブルで構成されるコードファーストのデータベース構造があります(EFはnn関係自体を処理できますが、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; }
}

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

ユーザーがグループのメンバーでない場合に Breeze API コントローラーによって生成される JSON (正常に動作)

[
    {
        $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
    }
]

ユーザーがグループのメンバーである場合に Breeze API コントローラーによって生成される JSON (失敗)

[
    {
        $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
    }
]

将来の読者のために編集

以下のマーガビットの回答は問題を正しく特定していますが、参照を容易にするために、これを解決する最も簡単な方法は、ブリーズコントローラーでこれを行うことではありません。

var context = new MyContext();

しかし、代わりにこれを行う

var context = _myEFContextProvider.Context;

EFContextProvider は、独自のインスタンスでプロキシの作成と遅延読み込みを無効にするため、仮想を維持し、コンテキスト コンストラクターで遅延読み込みをグローバルに無効にすることを回避できます。

4

1 に答える 1

3

EFで遅延読み込みを使用している可能性があると思います。これが、ナビゲーション プロパティに動的プロキシがある理由です。

Breeze のドキュメントでは、遅延読み込みは Breeze のオプションではないと述べています。

遅延読み込み

関連するエンティティがリモート ストレージに存在するが、現在はキャッシュに存在しない可能性について、何度か言及しました。Breeze ナビゲーション プロパティは、キャッシュ内のエンティティのみを返します。

一部のシステムでは、関連エンティティがまだキャッシュにない場合、ナビゲーション プロパティがリモート ストレージから関連エンティティを自動的に取得します。このプロセスは、関連するエンティティが要求されたときにのみキャッシュに読み込まれるため、「遅延読み込み」または「遅延読み込み」と呼ばれることがよくあります。

遅延読み込みは Breeze オプションではありません。Breeze では、関連するエンティティを明示的に読み込む必要があります。それらをクエリして直接ロードするか、別のクエリの副産物として間接的にロードできます。

そのため、Lazy Load を無効にして、エンティティGroupsTypeエンティティを明示的にロードする必要があります。

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

ナビゲーション プロパティ

于 2013-09-26T15:56:19.373 に答える