1

我知道標題並不是最大的,但這是我真正想要完成的。從實體框架動態查詢實體與主實體的關聯

我有一個細節視圖,表示實體1及其關聯。我正在捕獲鍵/值對中的屬性名稱和值。我目前正在使用反射來將實體屬性設置爲非關聯的相應值。我懷疑這是最有效的方法,但我一直無法找到使用表達式樹的更好方法。因此,現在我需要根據這些實體關聯的主鍵將Entity1的關聯設置爲它們對應的實體,並將它們稱爲Entity2-4。

當迭代Entity1的屬性時,我不知道如何爲Entity2-4構造動態查詢並將Entity1.association設置爲相應的實體。這裏是我到目前爲止的代碼:

foreach (string k in e.Values.Keys) 
{ 
    if (e.Values[k] != null && !String.IsNullOrEmpty(e.Values[k].ToString())) 
    { 
     System.Type objectType = Entity1.GetType(); 
     PropertyInfo[] p = objectType.GetProperties(); 

     foreach (PropertyInfo pi in p) 
     { 
      // set Entity1.Property for non associations (works just fine) 
      if (pi.Name == k) 
      { 
       System.Type t = pi.PropertyType; 
       pi.SetProperty(e.Values[k].ToString(), Entity1); 
       break; 
      } 
      // when i see pi.Name contain Reference, I know I'm working on an association 
      else if (pi.Name.Contains("Reference")) 
      { 
       // k is in the form of Entity.Property 
       var name = pi.Name.Left("Reference"); 
       var keys = k.Split('.'); 
       var ent = keys[0]; 
       var prop = keys[1]; 
       if (name == ent) 
       { 
        // here I need to obtain an instance from the db 
        // ie generate my dynamic query to the Entity with the name 
        // contained within the var "ent" 

        // I tried using reflection and could instantiate the entity 
        // but it did me no good as I needed the entity from the db 

        var entityInstance = some dynamic query; 

        // here I need to set the association of Entity1 to entityInstance from above 
        // normally I would use reflection, but I'm not sure that would work 
        // since EntityReference is the actual property returned by reflection 
        Entity1.SetAssocation(prop, Entity2); 
        break; 
       } 
      } 
     } 
    } 
} 

編輯

基本上,我需要構建實體及其關聯實體,以便我可以提交給數據上下文。實體2到4存在於數據庫中,我需要查詢數據庫以獲取實例,以便將它們與我創建並要提交的新實體1相關聯。

我的基本模型:

ENTITY1

Entity1.ID 
Entity1.Prop1 
Entity1.Prop2 
Entity1.Prop3 
Entity1.Entity2 
Entity1.Entity3 
Entity1.Entity4 

ENTITY2

Entity2.ID 
Entity2.Name 

ENTITY3

Entity3.ID 
Entity3.Name 

Entity4

Entity4.ID 
Entity4.Name 
+1

您不應該需要任何反射來顯示網格中的數據。也許你最好展示你的實體模型(基本部分)和樣例輸出。一定會有一種更簡單的方式來實現你想要的。 – 2013-04-10 20:36:41

+0

我可以幫助協會發現部分 - 但我第二個什麼Gert說 - 這是不太可能的,除非你真的有一個獨特的情況。 – NSGaga 2013-04-10 20:39:13

+0

好吧,這是交易,我使用動態數據,並使用詳細信息視圖執行插入。但是我有需要在代碼中管理的屬性,所以我使用細節視圖來設置UI,我在DetailsView_ItemInserting事件中完成我的魔術,提交實體並在ItemInserting上調用Cancel,因爲我已經手動添加了實體。 – m4chine 2013-04-10 20:51:00

回答

3

我們對於如何獲得metadataDbContext的深入討論。這裏有幾個鏈接讓你開始。我會添加一些具體的評論。

How I can read EF DbContext metadata programmatically?

的簡短摘要(但你應該在那裏檢查更多):

using (var db = new MyDbContext()) 
{ 
    var objectContext = ((IObjectContextAdapter)db).ObjectContext; 
    var container = objectContext.MetadataWorkspace.GetEntityContainer(objectContext.DefaultContainerName, DataSpace.CSpace); 

    var dependents = ((EntitySet)(set)).ForeignKeyDependents; 
    var principals = ((EntitySet)(set)).ForeignKeyPrincipals; 
    var navigationProperties = ((EntityType)(set.ElementType)).NavigationProperties; 

    // and e.g. for many-to-many (there is more for other types) 
    ManyToManyReferences = navigationProperties.Where(np => 
     np.FromEndMember.RelationshipMultiplicity == RelationshipMultiplicity.Many && 
     np.ToEndMember.RelationshipMultiplicity == RelationshipMultiplicity.Many) 
     .Select(np => Extensions.CreateLambdaExpression<TEntity>(np.Name)) 
     .ToList(); 
} 

@Goran奧布拉多維奇做了偉大的工作包了一下,我開始爲一組可重複使用的查詢(我應有的學分給他:)。

我已經計算出其中所有其他種類的信息。這只是爲DataSpace.CSpace(這是最有用的),但也有DataSpace.SSpace等 - 這是更多的創建SQL查詢等。我會把大部分鏈接放在底部。


具體細節:
在你的情況下可能會有所幫助:
(注:我不是很確定你以後,但我想在這裏 guess什麼方向,你)

db.Set<Worker>().Find(1); 

是訪問DbSet對於特定實體的通用方法。

你也可以從Type構建它,如果你需要它是完全動態的,如...
(我一直想做到這一點:)

MethodInfo setMethod = typeof(DbContext).GetMethod("Set", new Type[]{}); 
MethodInfo genericSetMethod = setMethod.MakeGenericMethod(new Type[] { typeof(YourEntity) }); 
var set = genericSetMethod.Invoke(db, new object[] {}); 

把你的實體 - 或你的Type而不是typeof(YourEntity)

然後,您可以繼續查詢,例如Find(id) - 爲那個實體 - 獲得具體的價值等。

這是動態的,因爲它得到了 - 我不知道如果這就是你想要的 - 但我只是扔東西在這裏,以防萬一你需要它。

這應該讓你起步,至少我希望。


鏈接:
(全部都是我的帖子 - 有些人可能或多或少相關,但可能會幫助)
How I can read EF DbContext metadata programmatically?
How check by unit test that properties mark as computed in ORM model?
Get Model schema to programmatically create database using a provider that doesn't support CreateDatabase
Programmatic data transformation in EF5 Code First migration

+0

我想我應該提到我卡在EF1上。目前網3.5。我一直無法將DbContext引用的方法轉換爲ObjectContext等價物。有什麼建議麼? – m4chine 2013-04-15 17:53:26

+0

你應該有:)這是早期版本,並從那時起事情**變化很多**。現在它更穩定,兩者之間的微小變化。我不知道當時的語法是什麼,對不起。 – NSGaga 2013-04-15 19:03:31

+0

有什麼建議嗎? – m4chine 2013-04-16 19:22:17

0

所以,我沒無法動態執行此操作。但這是我的工作解決方案。任何人都可以建議如何動態執行此操作?

foreach (string k in e.Values.Keys) 
{ 
    if (e.Values[k] != null && !String.IsNullOrEmpty(e.Values[k].ToString())) 
    { 
     System.Type objectType = roster.GetType(); 
     PropertyInfo[] p = objectType.GetProperties(); 

     foreach (PropertyInfo pi in p) 
     { 
      if (pi.Name == k) 
      { 
       System.Type t = pi.PropertyType; 
       pi.SetProperty(e.Values[k].ToString(), roster); 
       break; 
      } 
      else if (pi.Name.Contains("Reference")) 
      { 
       var name = pi.Name.Left("Reference"); 
       var keys = k.Split('.'); 
       var entityName = keys[0]; 
       var prop = keys[1]; 
       if (name == entityName) 
       { 
        var val = e.Values[k].ToString(); 
        switch (pi.Name) 
        { 
         case "Entity2Reference": 
          Entity1.Entity2Reference.EntityKey = new EntityKey("MyEntities." + entityName + "s", prop, val); 
          break; 

         case "Entity3Reference": 
          Entity1.Entity3Reference.EntityKey = new EntityKey("MyEntities." + entityName + "s", prop, val); 
          break; 

         case "Entity4Reference": 
          Entity1.Entity4Reference.EntityKey = new EntityKey("MyEntities." + entityName + "s", prop, Int64.Parse(val)); 
          break; 
        } 
       } 
      } 
     } 
    } 
} 
+0

我知道這是非常古老的,但我想知道你是否曾經爲Core找到過這樣的東西。 – johnny 2018-03-02 21:54:18