【发布时间】:2012-11-30 18:13:34
【问题描述】:
使用 Breeze,在创建实体时填充 GUID 键的最简单方法是什么?
【问题讨论】:
使用 Breeze,在创建实体时填充 GUID 键的最简单方法是什么?
【问题讨论】:
我假设您的实体已配置为客户端负责为新实体设置 Guid 键。这是 Entity Framework Code First 实体的 Guid 键的默认值;就好像关键属性装饰有[DatabaseGenerated(DatabaseGeneratedOption.None)]
显而易见的方法是在创建实体之后,在将其添加到管理器之前设置密钥,例如:
函数 createFoo() { var foo = fooType.createEntity(); foo.id(breeze.core.getUuid()); // 敲除实现 manager.addEntity(foo); }这可能就是你所需要的。
另一方面,您可能会发现您正在许多地方创建新的Foos,并且由于某些奇怪的原因您不能使用createFoo 函数。您当然不想重复该代码。
您可以使用 id 设置行为扩展 Foo 实体类型,之后您就可以编写代码了:
有两种方法需要考虑 - 自定义构造函数和类型初始化器;两者都在“Extending Entities”中描述
构造函数
您可以在自定义构造函数中初始化密钥。 Breeze 在您创建实体和实现查询的实体时都会调用构造函数。 Breeze 会在物化时替换初始键值。
这是一个假设 Knockout 模型库的示例。
函数 Foo() { foo.id(breeze.core.getUuid()); // 使用 KO } // 获取 MetadataStore 的一种方法 var store = manager.metadataStore; // 使用 Foo 类型注册 ctor store.registerEntityTypeCtor("Foo", Foo);很简单。唯一的缺点是 Breeze 每次创建实体时都会生成一个 Guid,无论是创建一个新实体还是从查询中实现一个实体。在物化过程中浪费了精力,但那又怎样?好吧,我想可能会成为性能问题,尽管在我测量之前我不会这么认为。
初始化器
假设您测量了重复的 Guid 生成是一个严重的问题(真的?)。您可以改为在类型初始化程序中设置键,并且仅在创建新实体时调用 Guid 生成器。
Breeze 在将实体返回到应用程序之前在从查询中创建或具体化实体之后调用类型初始化器。显然,您不想覆盖数据库中的物化键,因此您将在分配之前测试键值以确保它不是真实的(即确保您正在修复创建的实体)。这是一个例子。
函数 fooInitializer(foo) { var emptyGuid = "00000000-0000-0000-0000-000000000000"; if (foo.id() !=== emptyGuid) { foo.id(breeze.core.getUuid()); } } var store = manager.metadataStore; // 注册初始化器;此示例中没有 ctor store.registerEntityTypeCtor("Foo", function(){}, fooInitializer);【讨论】:
breeze.core.getUuid 方法是一个未记录的、非官方的Breeze 实用程序。我认为它将成为官方的......也许会以不同的名字......但我无法确认。使用风险自负(就像我一样)或复制其实现并使其成为您自己的实用程序。
假设您在所有实体上都有一个 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);
}
这样,您不必为所有实体创建初始化程序。
【讨论】: