2016-10-17 27 views
0

我開發了一種方法,它在實體框架保存更改時重置緩存。我在objectContext_SavingChanges如何在實體框架中獲取關聯集結束集上的實體類型?

private void objectContext_SavingChanges(object sender, EventArgs e) 
    { 
     if (_cacheProvider != null) 
     { 
      var objectContext = (this as IObjectContextAdapter).ObjectContext; 
      var entries = 
       objectContext.ObjectStateManager.GetObjectStateEntries(EntityState.Modified | EntityState.Added); 
      var result = new List<string>(); 

      if (entries != null && entries.Any()) 
      { 
       foreach (var entry in entries.Where(entry => !entry.IsRelationship)) 
       { 
        var entity = entries.Select(r => r.Entity).FirstOrDefault(); 
        if (entity != null) 
        { 
         var genericTypeName = 
          typeof(List<>).MakeGenericType(ObjectContext.GetObjectType(entity.GetType()))?.ToString(); 
         _cacheProvider.ResetCache(genericTypeName); 
        } 
       } 

       foreach (var entry in entries.Where(entry => entry.IsRelationship)) 
       { 
        var set = entry.EntitySet as AssociationSet; 
        if(set !=null) 
        { 
         var firstEntitySet = set.AssociationSetEnds[0].EntitySet; 
         var secondEntitySet = set.AssociationSetEnds[1].EntitySet; 

         var firstEntitySetName = firstEntitySet.ElementType.FullName + "," + Assembly.GetExecutingAssembly().FullName; 
         var secondEntitySetName = secondEntitySet.ElementType.FullName + "," + Assembly.GetExecutingAssembly().FullName; 

         var firstGenericTypeName = 
          typeof(List<>).MakeGenericType((Type.GetType(firstEntitySetName)))?.ToString(); 

         var secondGenericTypeName = 
          typeof(List<>).MakeGenericType((Type.GetType(secondEntitySetName)))?.ToString(); 

         _cacheProvider.ResetCache(firstGenericTypeName); 
         _cacheProvider.ResetCache(secondGenericTypeName); 
        } 
       }      
      } 
     } 
    } 

它的偉大工程物體狀態條目的實體的項目,但對於關聯集不起作用處理此事件。我需要爲關係的其他方面的兩個實體重置緩存。 AssociationSet具有「FullName」屬性,但該屬性不包含實際的類型名稱。它包含類型和程序集名稱的簡稱,但不包含解決方案中的完整名稱空間。

例如,類型在解決方案中有真實全名DataAccess.Entities.CachedEntity,名稱空間:DataAccess.Entities,簡稱:CachedEntity。但關聯集中的全名將爲DataAccess.CachedEntity

我可以得到每個關係結束的完整名稱類型嗎?

回答

0

我決定這個任務,以便:

 var clrTypeNamespace = @"http://schemas.microsoft.com/ado/2013/11/edm/customannotation:ClrType"; 

     var firstEdmType = set.AssociationSetEnds[0]?.EntitySet?.ElementType; 
     var secondEdmType = set.AssociationSetEnds[1]?.EntitySet?.ElementType; 

     var firstType = firstEdmType?.MetadataProperties.SingleOrDefault(p => p.Name == clrTypeNamespace)?.Value as Type; 
     var secondType = secondEdmType?.MetadataProperties.SingleOrDefault(p => p.Name == clrTypeNamespace)?.Value as Type; 

我們可以使用CLR類型的命名clrTypeNamespace在EDM和找到真正的實體類型的MetadataProperties

此外,我們還可以使用導航性的判定對於每個關係的集合。但是,當關系的兩側都存在導航屬性時,這種解決方案對於情況是可變的。

 var asem = set.AssociationSetEnds[0].CorrespondingAssociationEndMember; 
     var propInfo = asem.MetadataProperties.SingleOrDefault(p => p.Name == "ClrPropertyInfo")?.Value as PropertyInfo;