Angularjs breezejs createEntity未定义

Angularjs breezejs createEntity未定义,angularjs,breeze,angularjs-directive,Angularjs,Breeze,Angularjs Directive,在AngularJS指令中,我为范围变量指定了一个新值: $scope.myPerson = { TiersId: 105191, Name: "John Smith" }; 最初,$scope.myPerson是从BreezeJS实体创建的 分配新值会触发AngularJS生成$scope.apply(),然后BreezeJS会截取该值。这就是事情变得复杂的时候 [编辑] 好的,我发现我需要使用我在dataContext中注册的EntityManager: $scope.myPerson =

在AngularJS指令中,我为范围变量指定了一个新值:

$scope.myPerson = { TiersId: 105191, Name: "John Smith" };
最初,$scope.myPerson是从BreezeJS实体创建的

分配新值会触发AngularJS生成$scope.apply(),然后BreezeJS会截取该值。这就是事情变得复杂的时候

[编辑]

好的,我发现我需要使用我在dataContext中注册的EntityManager:

$scope.myPerson =  myDataContext.createPerson({ TiersId: 105191, Name: "John Smith" });

  function createPerson(person) {
        return manager.createEntity("AccountOwner", person);
  }
现在,它在以下代码中失败:

  proto.createEntity = function (typeName, initialValues, entityState) {
    entityState = entityState || EntityState.Added;
    var entity = this.metadataStore
        ._getEntityType(typeName)
        .createEntity(initialValues);
    if (entityState !== EntityState.Detached) {
        this.attachEntity(entity, entityState);
    }
    return entity;
};
实体类型已知,但createEntity(initialValues)函数未定义。为什么

[编辑]

为了让事情更清楚,以下是相关的EF映射以及模型类:

public class MandateMappings : EntityTypeConfiguration<Mandate>
{
    public MandateMappings()
    {
        Property(m => m.IBAN).HasMaxLength(34).IsFixedLength().IsUnicode(false);

        Property(m => m.AccountOwner.Name).HasMaxLength(70);  
        Property(m => m.AccountOwner.City).HasMaxLength(500); 

        Property(m => m.CreatedBy).HasMaxLength(30);
        Property(m => m.UpdatedBy).HasMaxLength(30);
    }
}



public class Mandate : Audit
{  
    public string IBAN { get; set; }

    public AccountOwner AccountOwner { get; set; }

}

public class AccountOwner
{
    public string Name { get; set; }
    public string City { get; set; }
}

public abstract class Audit
{
    public DateTime CreatedDate { get; set; }
    public string CreatedBy { get; set; }
}
公共类强制映射:EntityTypeConfiguration
{
公共命令映射()
{
属性(m=>m.IBAN).HasMaxLength(34).IsFixedLength().IsUnicode(false);
属性(m=>m.AccountOwner.Name).HasMaxLength(70);
属性(m=>m.AccountOwner.City).HasMaxLength(500);
属性(m=>m.CreatedBy).HasMaxLength(30);
属性(m=>m.UpdatedBy).HasMaxLength(30);
}
}
公共类授权:审计
{  
公共字符串IBAN{get;set;}
公共帐户所有者{get;set;}
}
公共类帐户所有者
{
公共字符串名称{get;set;}
公共字符串City{get;set;}
}
公共抽象类审计
{
公共日期时间CreatedDate{get;set;}
通过{get;set;}创建的公共字符串
}
Edit:从v1.3.1开始,Breeze现在支持继承。
如果没有更多的上下文,我不能确定,但我猜问题是Breeze还没有关于entityType的元数据。通常这是通过第一次查询完成的,但是如果您在第一次查询之前创建实体,那么替代方法是在执行任何createEntity调用之前调用EntityManager.fetchMetadata()方法。fetchMetadata方法是异步的,即返回承诺,因此需要在承诺的“then”部分内执行createEntity调用。最近还有几篇类似于此的“Breeze”文章,其中有更多的细节和示例。

让我澄清一下,当Breeze支持某种形式的继承而不是“数据库继承”时,我的意思是什么

我的意思是,今天,服务器端的类可以是继承链的一部分,前提是该链对客户端不可见

以下是与该警告一致的一些条件:

  • 只有链中的“terminal”类(最派生的类)映射到数据库表

  • 超类上的属性是非公共的(例如,内部)或显式未映射的(例如,用
    [System.ComponentModel.DataAnnotations.Schema.NotMapped]修饰)

  • 方法可能出现在任何级别的任何类上,因为它们永远不会传输到客户端

下面是从
基类继承的
TodoItem
类的示例:

public class baseClass { public void DoNothing() {} internal string Foo { get; set; } } public class TodoItem :baseClass { public int Id { get; set; } [Required, StringLength(maximumLength: 30)] public string Description { get; set; } public System.DateTime CreatedAt { get; set; } public bool IsDone { get; set; } public bool IsArchived { get; set; } } 公共类基类 { public void DoNothing(){} 内部字符串Foo{get;set;} } 公共类TodoItem:基类 { 公共int Id{get;set;} [所需的字符串长度(最大长度:30)] 公共字符串说明{get;set;} public System.DateTime CreatedAt{get;set;} 公共布尔值为{get;set;} 公共布尔是归档的{get;set;} } 这在服务器上运行正常。在控制器中设置断点:执行
DoNothing()
和获取/设置
Foo
属性不会有问题

这是因为此结构没有客户端后果。
基类
派生后的元数据与以前没有什么不同。
Foo
属性和
DoNothing
方法对于客户端是不可见的……这与此服务作者的意图完全相同

这种安排在现实世界中非常常见,在现实世界中,业务模型的许多类通过基类共享功能

这不是故事的结尾,也不是我们认为人们在要求“继承”时所要求的。

我们认为人们想要我一直称之为“数据库继承”的东西,我的意思是继承链中的两个或多个类映射到不同的表

Breeze今天没有处理这个问题……部分原因是Breeze还不能理解描述继承层次结构的元数据

变通办法 如果您有一个在不同的类级别上定义了数据属性的类层次结构,该怎么办?您可以通过提供元数据描述来克服当前的障碍,从客户端的角度将层次结构展平

例如,假设您有一个
Person
类型,其中
FirstName
LastName
。并且
Person
派生自
entityBase
,它定义了
createdBy

如果您将Person*EntityType*定义为具有[
FirstName
LastName
、和
createdBy
]属性—本质上是使层次结构扁平化—一切都会很好

自动平铺层次结构 当然,这是一个PITA。我们可以采取的一种继承方法是,当您要求Breeze在服务器上生成元数据时,为您执行此扁平化


我很好奇:这就足够了吗?或者您真的需要在JavaScript客户端上知道
createdBy
属性属于基类。如果您真的需要知道,请告诉我原因。

我将尝试组合一个JSFIDLE。但是:我确实需要在加载所有数据(包括元数据)后创建此实体。事实上Breeze.Calling已知类型“AccountOwner”。\u getEntityType(typeName)确实返回一些内容,但它没有方法