2013-08-05 30 views
2

有沒有一種方法可以使用ObjectContext和DbContext的模型構建器?我們不想使用POCO,因爲我們已經定製了不更新整個對象的屬性代碼,但只更新修改後的屬性。我們還有很多使用EntityObject的序列化和審計代碼。如何在模型構建器中使用ObjectContext?

由於poco確實使用EntityObject創建代理,我們希望我們的類可以從EntityObject派生。我們不需要代理。我們也大量使用CreateSourceQuery。唯一的問題是EDMX文件和它的大連接字符串語法web.config。

有沒有什麼辦法可以擺脫EDMX文件?這將會很有用,因爲我們可以基於逆向工程數據庫動態編譯新類。

我也想用EntityObject而不是poco來使用DbContext。

內在邏輯保存更改


  1. 訪問修改的屬性是提供ObjectStateEntry,並將它們保存到與舊的審計值和新值
  2. 多數時候我們只需要檢查任何條件倍在導航屬性例如

User.EmailAddresses.CreateSourceQuery() 
    .Any(x=> x.EmailAddress == givenAddress); 

  1. 訪問屬性下,如XmlIgnore等,我們在很大程度上依賴於對性能定義的屬性。
+0

你可以添加一個你自定義屬性的例子嗎? – LunicLynx

回答

4

POCO的代理是一個動態創建的類,派生(繼承)一個POCO。它增加了先前在EntityObject中發現的功能,即延遲加載和更改跟蹤,只要POCO符合requirements。 POCO或其代理不包含如問題所示的EntityObject,而是代理包含EntityObject的功能。您無法(AFAIK)將ModelBuilder與EntityObject派生類型結合使用,並且您無法從POCO或代理獲取底層EntityObject,因爲沒有這樣的實體對象。

我不知道是什麼的ObjectContext功能?您現有的序列化和審計代碼中使用,但您可以通過鑄造DbContextIObjectContextAdapter和訪問IObjectContextAdapter.ObjectContext財產得到ObjectContextDbContext

編輯:在保存更改

1.訪問修改後的屬性是在ObjectStateEntry可用,並將它們保存到與舊的審計值和新值

您可以通過使用DbContext.ChangeTracker實現這一目標與波蘇斯。首先,您撥打DbContext.ChangeTracker.DetectChanges來檢測更改(如果您使用的代理服務器不是必需的,但不會受到傷害),然後使用DbCotnext.Entries.Where(e => e.State != EntityState.Unchanged && e.State != EntityState.Detached)獲取DbEntityEntry更改的實體列表以進行審覈。每個DbEntityEntry具有OriginalValuesCurrentValues,並且實際實體在屬性Entity中。

您還可以訪問ObjectStateEntry,如下所示。

2.大多數的我們只需要檢查的導航屬性的任何條件,例如時間:

User.EmailAddresses.CreateSourceQuery().Any(x=> x.EmailAddress == givenAddress); 

您可以利用IObjectContextAdapter如前所述使用CreateSourceQuery()用的DbContext。當你的ObjectContext你可以得到源查詢像這樣的相關結尾:

public static class DbContextUtils 
{ 
    public static ObjectQuery<TMember> CreateSourceQuery<TEntity, TMember>(this IObjectContextAdapter adapter, TEntity entity, Expression<Func<TEntity, ICollection<TMember>>> memberSelector) where TMember : class 
    { 
     var objectStateManager = adapter.ObjectContext.ObjectStateManager; 
     var objectStateEntry = objectStateManager.GetObjectStateEntry(entity); 
     var relationshipManager = objectStateManager.GetRelationshipManager(entity); 
     var entityType = (EntityType)objectStateEntry.EntitySet.ElementType; 
     var navigationProperty = entityType.NavigationProperties[(memberSelector.Body as MemberExpression).Member.Name]; 
     var relatedEnd = relationshipManager.GetRelatedEnd(navigationProperty.RelationshipType.FullName, navigationProperty.ToEndMember.Name); 

     return ((EntityCollection<TMember>)relatedEnd).CreateSourceQuery(); 
    }   
} 

這種方法不使用動態代碼是強類型的,因爲它使用的表達式。你可以這樣使用它:

myDbContext.CreateSourceQuery(invoice, i => i.details); 
+0

問題是訪問CreateSourceQuery和ObjectStateEntry。 –

+0

@AkashKava:好的,更新了答案。在建議的'CreateSourceQuery()'中,你有一個如何訪問'ObjectStateEntry'的例子。 –

+0

謝謝,一旦我得到它,我將會並且會獎勵賞金。 –

相關問題