BreezeJS 修改后的路线不起作用
BreezeJS modified route not working
我的应用程序有两个具有完全相同架构的数据库。基本上,我需要根据我正在访问的数据更改 DbContext。一个 Db 中有两个国家,另一个 Db 中有 4 个国家。我希望客户决定使用哪个上下文。我尝试更改我的 BreezeWebApiConfig 文件,使路由看起来像这样:
GlobalConfiguration.Configuration.Routes.MapHttpRoute(
name: "BreezeApi",
routeTemplate: "breeze/{dbName}/{controller}/{action}/{id}",
defaults: new {id=RouteParameter.Optional,dbName="db1"}
);
我将字符串添加到控制器操作中:
[HttpGet]
public string Metadata(string dbName="")
{
return _contextProvider.Metadata();
}
并更改了 entityManager 服务名称。
现在,当客户端启动时,它会访问相应的元数据操作,我收到一条消息:
Error: Metadata query failed for: /breeze/clienthistory/kenya/Metadata. Unable to either parse or import metadata: Type .... already exists in this MetadataStore
当我从浏览器转到元数据 url 时,我得到了正确的元数据(与我从路由中删除 {dbName} 段时完全相同)。如果我从路线中删除 {dbName} 段,我不会收到任何错误并且一切正常
(我还没有开始实施多上下文——我只是想让额外的部分起作用)。
谢谢。
我认为问题在于您的 Breeze 客户端针对相同的元数据发出了两个单独的请求,在两个 "serviceNames" 的每一个下请求一次。 Breeze 试图将它们混合到同一个 EntityManager.metadataStore
中......但不能,因为那将意味着 EntityType
名称的重复。
一种可行的方法是通过在应用程序启动时立即获取元数据来启动您的应用程序,然后将所有关联的 "DataServiceNames" 添加到 MetadataStore
。
沿着这些方向尝试一些事情 (pseudo-code):
var manager;
var store = new breeze.MetadataStore();
return store.fetchMetadata(serviceName1)
.then(gotMetadata)
.catch(handleFail);
function gotMetadata() {
// register the existing metadata with each of the other service names
store.addDataService(new breeze.DataService(serviceName2));
... more services as needed ...
manager = new breeze.EntityManager({
dataService: store.getDataService(serviceName1), // service to start
metadataStore: store
});
return true; // return something
}
备选
要考虑的其他方法不涉及 'db' 基础 URL 中的占位符,也不涉及 Web API 路由。假设您在这方面使用基本服务名称
var serviceName = '/breeze/clienthistory/';
..
例如,您可以根据需要通过 withParameters
clause.
向您的路线添加一个可选参数(我们称之为 db
)
这是一个查询:
return new breeze.EntityQuery.from('Clients')
.where(...)
.withParameters({db: database1}); // database1 == 'kenya'
.using(manager).execute()
.then(success).catch(failed);
产生一个 URL 像:
/breeze/clienthistory/Clients/?$filter=...&db=kenya
它发出隐含的 first-time-only 元数据请求,解析为:
/breeze/clienthistory/Metadata
您的 server-side Web API 查询方法可以期望 db
作为可选参数:
[HttpGet]
public string Metadata(string db="")
{
... do what is right ...
}
保存?
我假设您在保存时也想识别目标数据库。您可以通过多种方式将其包含在保存请求中
- 在自定义 HTTP header 中通过 a custom AJAX adapter(您也可以对查询执行此操作)
- 在
saveChanges
POST 请求 URL 的查询字符串参数或散列段中(再次通过自定义 AJAX 适配器)。
- 中的
tag
中的属性中的saveOptions
中的object(容易被服务器实现SaveChanges
访问)
- 中的
resourceName
属性中的saveOptions
object(参见“named save”)
您需要自行探索各种选项,以找到最适合您的选择。
我的应用程序有两个具有完全相同架构的数据库。基本上,我需要根据我正在访问的数据更改 DbContext。一个 Db 中有两个国家,另一个 Db 中有 4 个国家。我希望客户决定使用哪个上下文。我尝试更改我的 BreezeWebApiConfig 文件,使路由看起来像这样:
GlobalConfiguration.Configuration.Routes.MapHttpRoute(
name: "BreezeApi",
routeTemplate: "breeze/{dbName}/{controller}/{action}/{id}",
defaults: new {id=RouteParameter.Optional,dbName="db1"}
);
我将字符串添加到控制器操作中:
[HttpGet]
public string Metadata(string dbName="")
{
return _contextProvider.Metadata();
}
并更改了 entityManager 服务名称。
现在,当客户端启动时,它会访问相应的元数据操作,我收到一条消息:
Error: Metadata query failed for: /breeze/clienthistory/kenya/Metadata. Unable to either parse or import metadata: Type .... already exists in this MetadataStore
当我从浏览器转到元数据 url 时,我得到了正确的元数据(与我从路由中删除 {dbName} 段时完全相同)。如果我从路线中删除 {dbName} 段,我不会收到任何错误并且一切正常
(我还没有开始实施多上下文——我只是想让额外的部分起作用)。
谢谢。
我认为问题在于您的 Breeze 客户端针对相同的元数据发出了两个单独的请求,在两个 "serviceNames" 的每一个下请求一次。 Breeze 试图将它们混合到同一个 EntityManager.metadataStore
中......但不能,因为那将意味着 EntityType
名称的重复。
一种可行的方法是通过在应用程序启动时立即获取元数据来启动您的应用程序,然后将所有关联的 "DataServiceNames" 添加到 MetadataStore
。
沿着这些方向尝试一些事情 (pseudo-code):
var manager;
var store = new breeze.MetadataStore();
return store.fetchMetadata(serviceName1)
.then(gotMetadata)
.catch(handleFail);
function gotMetadata() {
// register the existing metadata with each of the other service names
store.addDataService(new breeze.DataService(serviceName2));
... more services as needed ...
manager = new breeze.EntityManager({
dataService: store.getDataService(serviceName1), // service to start
metadataStore: store
});
return true; // return something
}
备选
要考虑的其他方法不涉及 'db' 基础 URL 中的占位符,也不涉及 Web API 路由。假设您在这方面使用基本服务名称
var serviceName = '/breeze/clienthistory/';
..
例如,您可以根据需要通过 withParameters
clause.
db
)
这是一个查询:
return new breeze.EntityQuery.from('Clients')
.where(...)
.withParameters({db: database1}); // database1 == 'kenya'
.using(manager).execute()
.then(success).catch(failed);
产生一个 URL 像:
/breeze/clienthistory/Clients/?$filter=...&db=kenya
它发出隐含的 first-time-only 元数据请求,解析为:
/breeze/clienthistory/Metadata
您的 server-side Web API 查询方法可以期望 db
作为可选参数:
[HttpGet]
public string Metadata(string db="")
{
... do what is right ...
}
保存?
我假设您在保存时也想识别目标数据库。您可以通过多种方式将其包含在保存请求中
- 在自定义 HTTP header 中通过 a custom AJAX adapter(您也可以对查询执行此操作)
- 在
saveChanges
POST 请求 URL 的查询字符串参数或散列段中(再次通过自定义 AJAX 适配器)。 - 中的
tag
中的属性中的saveOptions
中的object(容易被服务器实现SaveChanges
访问) - 中的
resourceName
属性中的saveOptions
object(参见“named save”)
您需要自行探索各种选项,以找到最适合您的选择。