使用Breeze,在创建实体时填充GUID键的最简单方法是什么?
答案 0 :(得分:15)
我假设您的实体已配置为客户端负责为新实体设置Guid密钥。这是Entity Framework Code First实体的Guid密钥的默认值;好像关键属性是用[DatabaseGenerated(DatabaseGeneratedOption.None)]
显而易见的方法是在创建实体之后以及在将其添加到管理器之前设置密钥,例如:
function createFoo() { var foo = fooType.createEntity(); foo.id(breeze.core.getUuid()); // Knockout implementation manager.addEntity(foo); }
这可能就是你所需要的一切。
另一方面,您可能会发现您在许多地方创建了新的 Foos ,并且由于某些奇怪的原因您无法使用createFoo
功能。你当然不想重复那段代码。
您可以使用id设置行为扩展Foo
实体类型,之后您就可以编写:
function createFoo() { var foo = fooType.createEntity(); // foo.id is set for you manager.addEntity(foo); }
有两种方法需要考虑 - 自定义构造函数和类型初始值设定项;两者都在“Extending Entities”
中描述<强> 构造 强>
您可以在自定义构造函数中初始化键。 Breeze在您创建实体时以及在实现查询实体时都会调用构造函数。 Breeze将在实现时替换初始键值。
这是一个假设Knockout模型库的例子。
function Foo() { foo.id(breeze.core.getUuid()); // using KO } // one way to get the MetadataStore var store = manager.metadataStore; // register the ctor with the Foo type 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 :(得分: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);
}
这样,您就不必为所有实体创建初始化程序。