Entity Framework 一个表多个外键关联另外一张表的相同主键

一. 报错

异常:System.Data.Entity.Infrastructure.DbUpdateException: 更新条目时出错。有关详细信息,请参阅内部异常。 ---> System.Data.Entity.Core.UpdateException: 更新条目时出错。有关详细信息,请参阅内部异常。 ---> MySql.Data.MySqlClient.MySqlException: Unknown column 'o_sawEntity_SawId' in 'field list'

二. 分析

clipboard

在输出的日志中,可以看到竟然生成三个不存在的列

clipboard

三. 解决方案

1. T4模板修改, 外键属性加上特性 [ForeignKey(“”)]

改造NavigationProperty方法

为了避免从属性上看,不知道是哪个外键的关联,统一都加上了外键列的名称(非常的丑陋,但是好用T^T)

  1     public string NavigationProperty(NavigationProperty navProp)
  2     {
  3         var endType = _typeMapper.GetTypeName(navProp.ToEndMember.GetEntityType()) + "Entity";
  4         return string.Format(
  5             CultureInfo.InvariantCulture,
  6             @"{5}
  7             {0} {1} {2} {{ {3}get; {4}set; }}
  8 ",
  9             AccessibilityAndVirtual(Accessibility.ForNavigationProperty(navProp)),
 10             navProp.ToEndMember.RelationshipMultiplicity == RelationshipMultiplicity.Many ? ("ICollection<" + endType + ">") : endType,
 11             _code.Escape(navProp) + "_" + ((System.Data.Entity.Core.Metadata.Edm.AssociationType)navProp.RelationshipType).ReferentialConstraints[0].ToProperties[0].Name,
 12             _code.SpaceAfter(Accessibility.ForGetter(navProp)),
 13             _code.SpaceAfter(Accessibility.ForSetter(navProp)),
 14             navProp.ToEndMember.RelationshipMultiplicity != RelationshipMultiplicity.Many
 15                 ? "[ForeignKey(\""+((System.Data.Entity.Core.Metadata.Edm.AssociationType)navProp.RelationshipType).ReferentialConstraints[0].ToProperties[0].Name+"\")]" // 确保主子表、父子关系插入时报错的问题
 16                 : ""
 17             );
 18     }

2. T4模板修改, 在列表属性上特性 [InverseProperty("")]

  1     var navigationProperties = typeMapper.GetNavigationProperties(entity);
  2     if (navigationProperties.Any())
  3     {
  4 #>
  5 
  6 <#
  7         foreach (var navigationProperty in navigationProperties)
  8         {
  9             if (navigationProperty.ToEndMember.RelationshipMultiplicity == RelationshipMultiplicity.Many)
 10             {
 11                   // 多个外键指向同一个表
 12                   var inverseProperty = allNavigationProperties
 13                                 .FirstOrDefault(a => a.RelationshipType.Name == navigationProperty.RelationshipType.Name
 14                                                   && a.Name != navigationProperty.Name);
 15                   if(inverseProperty != null){
 16                         var foreignKeyName= ((System.Data.Entity.Core.Metadata.Edm.AssociationType)navigationProperty.RelationshipType)
 17                                 .ReferentialConstraints[0].ToProperties[0].Name;
 18 #>
 19 
 20                 [InverseProperty("<#=inverseProperty.Name + "_" + foreignKeyName#>")]
 21 <#
 22                   }
 23 #>
 24                 [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
 25 <#
 26             }
 27 #>
 28     <#=codeStringGenerator.NavigationProperty(navigationProperty)#>
 29 <#
 30         }
 31     }
 32 #>

3. 最终效果

clipboard

4. 编码

clipboard

在列表属性中加上entity,并标识为Added

posted @ 2019-11-21 15:47  远方V3  阅读(1203)  评论(0编辑  收藏  举报