0

请跳过此并阅读编辑:)

我有一个实体,它为其他两个实体提供多对多映射:

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);
        }

在服务中(使用微风)我将数据发送到 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: 函数(数据){ 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,然后我决定使用角度的$timeout并等待几秒钟然后记录ExerciseId,之后ExerciseId大于-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);
            }
        },

最后,我知道这是一个非常糟糕的解决方案,我的问题是,我该如何解决这个问题?有什么方法可以让我知道Exercise 已插入数据库并且ExerciseId 不再是-1 了吗?或者我可以在客户端生成ExerciseId(它是int)吗?

4

1 回答 1

0

Breeze 还不支持实体框架的多对多关系,尽管它在我们的路线图中。请在此处为 Breeze User Voice 投票。作为一种解决方法,您可以使用两个一对多的关系,并将映射表作为中间的实体公开。

例如:如果您有这样的概念多对多关系:

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)

您仍然可以从 Employee 导航到其 Territories,反之亦然,但您需要先通过中间实体。

于 2013-08-18T21:57:56.053 回答