Breeze:如何在客户端创建新实体的GUID键?

11
使用Breeze,当创建一个实体时,最简单的方法是如何填充GUID键?
2个回答

15

假设您的实体已配置为客户端负责为新实体设置 Guid 键。这是 Entity Framework Code First 实体的 Guid 键的默认值;就好像键属性装饰有[DatabaseGenerated(DatabaseGeneratedOption.None)]一样。

显而易见的方法是在创建实体之后,在将其添加到管理器之前设置键,例如:

function createFoo() {
    var foo = fooType.createEntity(); 
    foo.id(breeze.core.getUuid()); // Knockout实现
    manager.addEntity(foo);
}

这可能是您需要的全部内容。

另一方面,您可能会发现您在许多地方创建新的Foos,但由于某种奇怪的原因,您无法使用createFoo函数。 您肯定不想重复该代码。

您可以使用设置id的行为扩展Foo实体类型,之后您将能够编写:

function createFoo() {
    var foo = fooType.createEntity(); // 为您设置了foo.id
    manager.addEntity(foo);
}

有两个方法可供考虑-自定义构造函数和类型初始化程序;两者都在“扩展实体”中描述

构造函数

您可以在自定义构造函数中初始化键。当创建实体并材料化查询的实体时,Breeze 都会调用构造函数。 在材料化时,Breeze 将替换初始键值。

这是一个假设使用 Knockout 模型库的示例。

function Foo() {
    foo.id(breeze.core.getUuid()); // 使用KO
}
// 获取MetadataStore的一种方法 var store = manager.metadataStore; // 使用Foo类型注册ctor store.registerEntityTypeCtor("Foo", Foo);
很简单。唯一的缺点是,Breeze每次创建一个实体时(无论是创建新的实体还是从查询中实例化一个实体),都会生成一个Guid。这在实例化过程中是浪费的,但又怎样呢?好吧,我想可能会成为性能问题,尽管在测量之前我不会这么认为。
初始化器 假设您已经测量过,重复的Guid生成是一个严重的问题(真的吗?)。您可以在类型初始化器中设置键,并仅在创建新实体时调用Guid生成器。 Breeze在创建或从查询中实例化实体后调用类型初始化器,然后将该实体返回给应用程序。显然,您不希望覆盖来自数据库的实例化键,因此,在分配之前,您将测试键值以确保它不是真实的(即确保您正在修复已创建的实体)。以下是一个示例。
function fooInitializer(foo) {
    var emptyGuid = "00000000-0000-0000-0000-000000000000";
    if (foo.id() !=== emptyGuid) {
        foo.id(breeze.core.getUuid());
    }
}
var store = manager.metadataStore; // register the initializer; no ctor in this example store.registerEntityTypeCtor("Foo", function(){}, fooInitializer);

1
上面提到的 breeze.core.getUuid 方法是一个未记录、非官方的 Breeze 工具。我认为它将成为官方工具...也许会有不同的名称...但我无法确认。使用时需自行承担风险(就像我一样),或者复制其实现并将其作为自己的工具。 - Ward
1
只是再确认一下:if语句中的感叹号是打错了吗? - user210757

1
假设您在所有实体上都有像我们这样的Guid代理键,您可以编写一个createInstance工厂来以非常通用的方式执行以下操作:
function createInstance(breezeEntityManager, typeName) {
    var keyProperty = breezeEntityManager.metadataStore.getEntityType(typeName, false).dataProperties.filter(function (p) {
        return p.isPartOfKey;
    })[0];
    var config = {};
    config[keyProperty.name] = breeze.core.getUuid();
    return breezeEntityManager.createEntity(typeName, config);
}

这样,您就不必为所有实体创建初始化器。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接