Entity Framework 一个表多个外键关联另外一张表的相同主键
一. 报错
异常:System.Data.Entity.Infrastructure.DbUpdateException: 更新条目时出错。有关详细信息,请参阅内部异常。 ---> System.Data.Entity.Core.UpdateException: 更新条目时出错。有关详细信息,请参阅内部异常。 ---> MySql.Data.MySqlClient.MySqlException: Unknown column 'o_sawEntity_SawId' in 'field list'
二. 分析
在输出的日志中,可以看到竟然生成三个不存在的列
三. 解决方案
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. 最终效果
4. 编码
在列表属性中加上entity,并标识为Added
欢迎在评论区留下你宝贵的意见,不论好坏都是我前进的动力(cnblogs 排名提升)!
如果喜欢,记得点赞、推荐、关注、收藏、转发 ... ;)