实体框架,以多对多关系发布保存数据

时间:2015-01-12 12:54:27

标签: c# asp.net-mvc entity-framework repository-pattern

我发现在两个表之间以多对五的关系保存数据,通过在两个表之间引入另一个表来中断,包含两者的主键。我有代码第一个现有的数据库方法以及MVC应用程序中的存储库模式和工作单元

enter image description here

这是我的模型类

Navigation_Functions

public class Navigation_Functions
{
    public Navigation_Functions()
    {

    }
    [Key]
    public int Function_ID { get; set; }

    [StringLength(250)]
    [Required(ErrorMessage = "Required Title")]
    [Display(Name = "Function Title")]
    public string FunctionName { get; set; }

    [Required(ErrorMessage = "Required Hierarchy Level")]
    [Display(Name = "Hierarchy Level")]
    public int Hierarchy_Level { get; set; }

    public ICollection<Navigation_FunctionController> Navigation_FunctionController { get; set; }
  }
}

Navigation_FunctionController模型

 public class Navigation_FunctionController
{
    public Navigation_FunctionController()
    {

    }

    [Key]
    public int ControllerID { get; set; }

    [StringLength(250)]
    [Required]
    public string ControllerName { get; set; }

   public ICollection <Navigation_Functions> Navigation_Functions { get; set; }

}

交汇点模型

 [Table("Navigation_FunctionInController")]
public class Navigation_FunctionInController
{
    public Navigation_FunctionInController() 
    { 

    }

    [Key]
    public int FunctionInController_ID { get; set; }

    [Key]
    [ForeignKey("Navigation_Functions")]
    public int Function_ID { get; set; }

    [Key]
    [ForeignKey("Navigation_FunctionController")]
    public int ControllerID { get; set; }

    public Navigation_FunctionController Navigation_FunctionController { get; set; }
    public Navigation_Functions Navigation_Functions { get; set; }

}

我有CRUD操作的通用存储库

public void InsertEntity(TEntity obj)
    {
        _DbSet.Add(obj);
    }

我的ViewModel

public class FunctionsNavigation_ViewModel 
{
    public Navigation_Functions _Navigation_Functions { get; set; }

    public Navigation_FunctionController _Navigation_FunctionController { get; set; }
}

 public void CreateFunctionNavigation(FunctionsNavigation_ViewModel _obj)
  {
    using (var _uow = new FunctionsNavigation_UnitOfWork())
        {
            try
            {                  
                var _navigationFunction = _obj._Navigation_Functions;

               _navigationFunction.Navigation_FunctionController = new List<Navigation_FunctionController>();

               _navigationFunction.Navigation_FunctionController.Add(_obj._Navigation_FunctionController);

               _uow.Navigation_Functions_Repository.InsertEntity(_navigationFunction);

               _uow.Save(); 
            }
            catch
            {

            }
        }
    }

如果我从上面的代码中删除以下行,那么它会保存新的Navigation_Functions

 _navigationFunction.Navigation_FunctionController.Add(_obj._Navigation_FunctionController);

以下是调试代码的截屏。

enter image description here

我想知道我的ViewModel是否正确?其次实体框架如何知道需要将两个表的主键放在Navigation_FunctionInController中?

1 个答案:

答案 0 :(得分:0)

当你的模特看起来像这样......

public class Navigation_Functions
{
    ...
    public ICollection<Navigation_FunctionController> Navigation_FunctionController { get; set; }
}

public class Navigation_FunctionController
{
    ...
    public ICollection <Navigation_Functions> Navigation_Functions { get; set; }
}

...因此,如果没有Navigation_FunctionInController类,数据库中的联结表(Navigation_FunctionInController)不会在类模型中表示。如果您首先拥有此模型代码,EF将自行创建一个联结表。如果您首先使用数据库,EF将不会创建联结类,并且在图中您将看到纯多对多关联,如下所示:*--*。但这只有在联结表只包含两个外键时才会发生,这两个外键都包含复合主键。

在您的模型中,您有一个显式的联结类(可能因为该表除了两个外键之外还有一个主键字段)。这意味着多对多关联变为1:n:1关联。类模型应该基本上看起来像......

public class NavigationFunction
{
    ...
    public ICollection<NavigationFunctionInController> NavigationFunctionInControllers { get; set; }
}

public class NavigationFunctionController
{
    ...
    public ICollection <NavigationFunctionInController> NavigationFunctionInControllers { get; set; }
}

public class NavigationFunctionInController
{
    public int FunctionInControllerID { get; set; }

    [ForeignKey("NavigationFunction")]
    public int FunctionID { get; set; }

    [ForeignKey("NavigationFunctionController")]
    public int ControllerID { get; set; }

    public NavigationFunctionController NavigationFunctionController { get; set; }
    public NavigationFunction NavigationFunction { get; set; }

}

请注意,外键字段不必是主键的一部分(也不是我更喜欢单数名Navigation_Function和集合的多个名称,名称中没有下划线)。

因此,您的代码中发生的事情是您拥有1:n:1关联,但您尝试通过直接向m:n添加项目来管理_navigationFunction.Navigation_FunctionController关联。但EF不跟踪该集合,并且不保存这些项目。

相反,您必须创建一个联结类实例...

var nfic = new NavigationFunctionInController
            {
                NavigationFunction = obj.NavigationFunction,
                NavigationFunctionController = obj.Navigation_FunctionController
            };

...并通过您的存储库和UoW保存。