请跳过此内容并阅读编辑内容:)
我有实体,可以为其他两个实体提供多对多的映射:
public class ExerciseAndCategory
{
#region Navigational properties
public int CategoryId { get; set; }
public virtual ExerciseCategory ExerciseCategory { get; set; }
public int ExerciseId { get; set; }
public virtual Exercise Exercise { get; set; }
#endregion
}
这是FluentApi:
modelBuilder.Entity<ExerciseAndCategory>().HasKey(e => new {e.ExerciseId, e.CategoryId});
modelBuilder.Entity<ExerciseAndCategory>()
.HasRequired(e => e.Exercise)
.WithMany()
.HasForeignKey(e => e.ExerciseId)
.WillCascadeOnDelete(true);
modelBuilder.Entity<ExerciseAndCategory>()
.HasRequired(e => e.ExerciseCategory)
.WithMany()
.HasForeignKey(e => e.CategoryId)
.WillCascadeOnDelete(true);
在数据库中看起来像这样:
使用BreezeApi控制器获取和保存数据,我在微风样本中显示数据:
[HttpPost]
public SaveResult SaveChanges(JObject saveBundle)
{
return _contextProvider.SaveChanges(saveBundle);
}
在服务中(使用Breeze)我将数据发送到api,如下所示:
addExerciseAndCategories: function (data, initialValues) {
var addedExercise = manager.createEntity("Exercise", initialValues);
_.forEach(data, function (item) {
var entity = manager.createEntity("ExerciseAndCategory", { ExerciseId: addedExercise._backingStore.ExerciseId, CategoryId: item.CategoryId });
items.push(entity);
});
saveChanges().fail(addFailed);
function addFailed() {
removeItem(items, item);
}
},
有了这个我可以添加项目到数据库,但如果我想添加另一个没有刷新,
我在这部分代码中遇到异常:
[HttpPost]
public SaveResult SaveChanges(JObject saveBundle)
{
return _contextProvider.SaveChanges(saveBundle);
}
说
DBUpdateException was unhandeled by user code
An error occurred while updating the entries. See the inner exception for details.
在Javascript控制台中:
"Error: Error: The INSERT statement conflicted with the FOREIGN KEY constraint "FK_dbo.ExerciseAndCategories_dbo.Exercises_ExerciseId". The conflict occurred in database "aspnet-Web.UserInterface.Web-20130806182934", table "dbo.Exercises", column 'ExerciseId'.
The statement has been terminated."
但如果我在添加后刷新,一切正常。 (即我可以添加另一个项目)
修改
我发现问题的解决方法非常糟糕。问题是,在调用saveChanges()之前,ExerciseId为-1。我决定在两个不同的功能中分别添加练习和类别。我的代码看起来像这样:
addExercise: function (initialValues) {
exerciseToAdd = manager.createEntity("Exercise", initialValues);
saveChanges().fail(addFailed);
function addFailed() {
removeItem(items, item);
}
},
addExerciseAndCategories:function(data){ newItems = [];
logger.log("id is", exerciseToAdd.ExerciseId);
_.forEach(data, function(item) {
var entity = manager.createEntity("ExerciseAndCategory", { ExerciseId: exerciseToAdd.ExerciseId, CategoryId: item.CategoryId });
items.push(entity);
newItems.push(entity);
});
saveChanges().fail(addFailed);
var itemsToAdd = addCategoriesToExercise(newItems);
_.forEach(itemsToAdd, function(item) {
exerciseAndCategories.push(item);
});
}
这并没有奏效,同样的错误。所以在控制台中我注意到ExerciseId仍然是-1,然后我决定使用angular&#39; s $ timeout并等待几秒然后记录ExerciseId,之后ExerciseId的int大于-1,即它工作正常,所以我已经改变了代码(一切都按预期工作):
addExerciseAndCategories: function(data) {
newItems = [];
$timeout(function() {
logger.log("id je", exerciseToAdd.ExerciseId);
_.forEach(data, function (item) {
var entity = manager.createEntity("ExerciseAndCategory", { ExerciseId: exerciseToAdd.ExerciseId, CategoryId: item.CategoryId });
items.push(entity);
newItems.push(entity);
});
saveChanges().fail(addFailed);
var itemsToAdd = addCategoriesToExercise(newItems);
_.forEach(itemsToAdd, function(item) {
exerciseAndCategories.push(item);
});
},5000);
function addFailed() {
removeItem(items, item);
}
},
最后,我知道这是一个非常糟糕的解决方案,我的问题是,我该如何解决这个问题呢?有没有办法让我知道练习被插入到数据库中,而且ExerciseId不再是-1?或者我可以在客户端生成ExerciseId(这是int)吗?
答案 0 :(得分:0)
Breeze尚未支持实体框架的多对多关系,尽管它在我们的路线图中。请在Breeze用户语音here上投票。作为一种解决方法,您可以使用两个一对多的关系,您的映射表在中间公开为实体。
例如:如果你有这样一个概念上的多对多关系:
Employee (m) <--> (m) Territory
Properties: Employee.Territories (m)
Territory.Employees (m)
您可以通过在中间添加新的EntityType(EmpTerritory)来构建它:
Employee (1) <--> (m) EmpTerritory (m) <--> Territory (1)
Properties: Employee.EmployeeTerritories (m),
Territory.EmployeeTerritories (m),
EmployeeTerritory.Employee (1),
EmployeeTerritory.Territory (1)
您仍然可以从员工导航到其地区,反之亦然,但您需要首先通过中间实体。