我正在为大型企业,面向数据的Angular 5应用程序评估Breeze.Js,以便利用vanilla Angular框架中缺少的以下功能:
出于测试目的,我在ASP.NET WebApi + EntityFramework服务器端编写了以下简单的BreezeController:
[EnableCors(origins: "*", headers: "*", methods: "*")]
[BreezeController]
public class PeopleController : ApiController
{
private AdventureWorksDbContext db = new AdventureWorksDbContext();
#region "Breeze"
readonly EFContextProvider<AdventureWorksDbContext> _contextProvider =
new EFContextProvider<AdventureWorksDbContext>();
// ~/breeze/todos/Metadata
[HttpGet]
public string Metadata()
{
return System.Text.Encoding.UTF8.GetString(AdventureWorks.WebApi.Properties.Resources.WebApiMetadata);
}
// ~/breeze/todos/Todos
// ~/breeze/todos/Todos?$filter=IsArchived eq false&$orderby=CreatedAt
[HttpGet]
public IQueryable<PersonDTO> GetPeople()
{
return db.People.ProjectTo<PersonDTO>();
}
// ~/breeze/todos/SaveChanges
[HttpPost]
public SaveResult SaveChanges(Newtonsoft.Json.Linq.JObject saveBundle)
{
return _contextProvider.SaveChanges(saveBundle);
}
#endregion
}
正如您在我的示例中所看到的(它使用AdventureWorks DB),我已做了以下修改: 1)&#34; GetPeople()&#34; endpoint返回DTO的可查询对象(&#34; ProjectTo&#34;扩展由Automapper提供)。我需要这样做,以便为客户端以可用的方式塑造模型,避免递归,深入了解模式,大字段序列化等等。
2)&#34;元数据()&#34; endpoint返回表示DTO类元数据的字符串资源。我使用&#34; PocoMetadata&#34;来构建它。 &#34; Breeze工具套件的工具&#34; (https://github.com/Breeze/breeze.tooling)。这是必要的,因为只要我使用DTO而非EF POCO类,我就无法返回_contextProvider.Metadata()
结果。
现在,如果在我的Angular 5客户端中发出如下所示的ODATA查询,我可以看到executeQuery()
方法确实有效:
export class BreezeDataStoreComponent implements OnInit {
private _em: EntityManager;
constructor() {
this._em = new EntityManager({
serviceName: 'http://localhost:31328/breeze/People'
});
}
ngOnInit() {
const query = EntityQuery.from('GetPeople')
.where('FirstName', FilterQueryOp.StartsWith, 'F')
.orderBy('LastName', true);
this._em.executeQuery(query).then(res => {
// Here i can get all People instances.
// Now i try to get the first, edit the name and saveChanges.
(res.results[0] as any).FirstName = 'Franklino';
this._em.saveChanges().then(saveResult => {
const test = saveResult.entities;
});
});
}
}
不幸的是SaveChanges()
会出现问题。
当Angular客户端调用该方法时,在我的服务器端,我收到以下错误:
System.InvalidOperationException:Sequence不包含匹配项 元件
我认为这是因为我通过EF上下文提供程序调用SaveChanges(),传递一个引用DTO而不是POCO类的JObject bundle。
所以我的问题是:
是否可以使用DTO&#39;来使用BreezeJs查询和批量持久性(SaveChanges()方法)?在以数据为中心的大型企业应用程序中,这是一个非常普遍的需求,因为我认为在WebApi上暴露EF POCO是一种不好的做法。
我应该依赖于响应POST \ PUT \ DELETE HTTP动词的经典WebApi吗?在这种情况下,如何配置Breeze客户端以联系这些端点而不是&#34; SaveChanges&#34;什么时候保持数据?
如果Breeze不适合这种需求,还有其他技术可以提供上述4点吗?
非常感谢。
答案 0 :(得分:1)
要使SaveChanges
与您的DTO一起使用,您需要
JObject saveBundle
或2号似乎是更好的选择。如果实体与DTO之间没有1:1的匹配,则在进行映射时需要一些逻辑。