<th id="v9g6b"><track id="v9g6b"></track></th>

  • <em id="v9g6b"><acronym id="v9g6b"></acronym></em>
    <progress id="v9g6b"><pre id="v9g6b"></pre></progress>
    <tbody id="v9g6b"></tbody>
    <button id="v9g6b"><acronym id="v9g6b"></acronym></button>
    <rp id="v9g6b"><ruby id="v9g6b"></ruby></rp>

        <dd id="v9g6b"></dd>

        <em id="v9g6b"></em>

          深入MVC框架--EF中的导航属性优势与弊端(一)

          Web开发框架中EF中提供了一个新鲜的东东--导航属性,某个模型的外键表数据可以自动加载,这样做确实提高了代码效率,那有什么弊端吗
          概述
          模型
          描述
          问题
          解决
          概述

          在关系数据库中,表之间的关系(也称为关联)是通过外键定义的。外键 (FK) 是用于在两个表的数据之间建立并强制链接的一列或列组合。有三种关系类型:一对一、一对多和多对多。在一对多关系中,外键是在表示关系多端的表上定义的。多对多关系涉及定义第三个表(也称为接合或联接表),主键由来自两个相关表的外键组成。在一对一关系中,主键还用作外键,两个表都没有单独的外键列。
          在实体框架中,实体可以通过关联(关系)与其他实体相关。每个关系都包含两端,它们描述关系中两个实体的实体类型以及类型的多重性(一、零或一、多)。关系可由引用约束控制,该引用约束描述了关系中的哪端为 Role 以及哪端为 Dependent,哪端为 Role 以及哪端为 Function
          导航属性为在两个实体类型间导航关联提供了一种方式。针对对象参与到其中的每个关系,各对象均可以具有导航属性。使用导航属性,可以在两个方向上导航和管理关系,返回引用对象(如果多重性为一或者零或一)或集合(如果多重性为多)。也可以选择使用单向导航,在这种情况下,只对参与关系的一种而不是两种类型定义导航属性。

          模型
          public partial class SystemRole : BaseEntity
          {
              public override int Id { get; set; }
              public string RoleName { get; set; }
              /// <summary>
              /// 所属的部门ID
              /// </summary>
              public int? DepartmentID { get; set; }
              [NotMapped]
              public Department Department { get; set; }
              public string DepartmentName
              {
                  get
                  {
                      if (Department != null)
                          return Department.DepartmentName;
                      return "";
                  }
              }
              public bool IsEnabled { get; set; }
              /// <summary>
              /// 该角色具备的功能操作集合。
              /// </summary>
              
              public IList<SystemFunction> Functions { get; set; }
          }
          /// <summary>
          /// SystemRole和SystemFunction的关联表
          /// </summary>
          public class SystemRoleFunction : BaseEntity
          {
                 
              public override int Id { get; set; }
              public int RoleID { get; set; }
                 
              public SystemRole Role { get; set; }
              public int FunctionID { get; set; }
                
              public SystemFunction Function { get; set; }
          }
          public class SystemFunction 
          {
              public  int Id { get; set; }
              public string FunctionCode { get; set; }
              public string FunctionName { get; set; }
              /// <summary>
              /// 定义的分组名称
              /// </summary>
              public string GroupName { get; set; }
              public int DisplayOrder { get; set; }
          }
          public IList<SystemRole> GetAllRoles(bool enabledOnly = true, bool loadingFunctions = false)
          {
              var queryable = this._roleRepository.TableNoTracking.Include(t => t.Department);
              if (enabledOnly)
                  queryable = queryable.Where(t => t.IsEnabled == true);
              var list = queryable.ToList();
              if (loadingFunctions)
              {
                  list.ForEach(r =>
                  {
                      var roleFuncDbSet = this._dbContext.Set<SystemRoleFunction>();
                      var funcDbSet = this._dbContext.Set<SystemFunction>();
                      var funcs = from re in roleFuncDbSet join f in funcDbSet on re.FunctionID equals f.Id where re.RoleID == r.Id select f;
                             
                      r.Functions = funcs.ToList();
                  });
              }
              return list;
          }
          描述

          模型关系:SystemRole 和SystemFuction多对多关系,通过SystemRoleFunction关联,关联字段RoleID、FunctionID;SystemRole与Department一对多关系,关联字段DepartmentID。
          前提:在Web开发框架中我们并没有采用EF Fluent API使用EntityTypeConfiguration分文件配置Model映射关系,我们只在DBContext中为模型添加了DbSet

          问题

          我们跑下代码,看下是否配置正确。发现以下两个错误:

          错误1
          错误2
          解决

          我们可以看到,都是两个外键惹的祸, 都是需要加载外键相关表的数据,但是都没有加载出来。我们看第一个的现象“SystemRoledId”无效, 从linq语句我们可以看出两个关联模型:SystemRoleFunction和SystemFunction , SystemFunction与SystemRole通过SystemRoleFunctiond的RoleID、FunctionID关联,这个错误说明模型中某个导航属性加载时没有找到相关的外键, 我们来瞧瞧是哪个模型,看哪个数据模型用了导航属性但是没有相关外键的,我们在上面的三个模型里找找看,哦,原来是SystemRole的这段public IList<SystemFunction> Functions { get; set; },Oh,My God,原来在这儿, 明白了,那么我们怎么解决呢,我们的外键是设在SystemRoleFunction这个关联表中,看来在这而添加外键不现实,看来我们只能取消这个导航属性了,把他作为一个数据集,由代码来给这个数据集赋值,在该代码上加上[NotMapped]的特性,运行后结果正常

          错误解决1

          好了,来看下我们的第二个错误现象,我也有红色字体注明了加上NotMapped后出现的错误,加上后我们就找不到外键关联的导航属性,故而报错,更深层次大家可以看EF相关源码是最直观的思考方式。我们去掉该特性后可以看到结果已经正常。

          网站&系统开发技术学习交流群:463167176

          本站文章除注明转载外,均为本站原创或翻译,欢迎任何形式的转载,但请务必注明出处,尊重他人劳动,共创和谐网络环境。
          转载请注明:文章转载自:华晨软件-云微开发平台 ? 深入MVC框架--EF中的导航属性优势与弊端(一)
          本文标题:深入MVC框架--EF中的导航属性优势与弊端(一)
          本文地址:http://www.sajuice.com/OrgTec/DB/0003.html

          相关文章: 初识Web框架--C# Linq技术基础

          电话
          电话 18718672256

          扫一扫
          二维码
          本港台开奖 <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <文本链> <文本链> <文本链> <文本链> <文本链> <文本链>