2012-12-17 130 views
0

假设您有一个纯业务层中创建的POCO对象(例如Customer),然后调用context.Add(customer)。你已经通过并参考的Customer对象会被跟踪吗?换句话说:你在ObjectStateManager跟踪的同一个对象中传递的对象,还是不同的对象?实体框架代码第一个和实体跟踪

如果它们不是相同的对象,是不是会导致大量的内存消耗,因为有两个对象图始终保持着:一个由您(开发人员)在业务层中,另一个由ObjectStateManager在DAL中?

+0

这篇文章解释了一些有关更改跟踪与波苏斯是如何工作的。 http://blogs.msdn.com/b/adonet/archive/2009/06/10/poco-in-the-entity-framework-part-3-change-tracking-with-poco.aspx –

+0

@ MalcolmO'Hare ,我浏览了文章,但我似乎没有谈论这个特殊情况。 –

回答

0

上下文的想法是不要让它变得太大。即使有多个具有不同数据视图的上下文。甚至可以使用每个工作单元的新环境。 所以是的,它可以变大。关于此主题的一些很好的阅读 搜索有界上下文和Luw模式。例如来自Julie Lerman。

这里是由EF管理的反编译的IEntityWrapper(来自EF5.0/Net 4.0) 在将实体放入ObjectContext时使用了IENtityWrapper。

我让你决定它是否大。
通过毫米波提到的参考是object Entity { get; } // see below inside wrapper

internal interface IEntityWrapper 
{ 
void EnsureCollectionNotNull(RelatedEnd relatedEnd); 
EntityKey GetEntityKeyFromEntity(); 
void AttachContext(ObjectContext context, EntitySet entitySet, MergeOption mergeOption); 
void ResetContext(ObjectContext context, EntitySet entitySet, MergeOption mergeOption); 
void DetachContext(); 
void SetChangeTracker(IEntityChangeTracker changeTracker); 
void TakeSnapshot(EntityEntry entry); 
void TakeSnapshotOfRelationships(EntityEntry entry); 
void CollectionAdd(RelatedEnd relatedEnd, object value); 
bool CollectionRemove(RelatedEnd relatedEnd, object value); 
object GetNavigationPropertyValue(RelatedEnd relatedEnd); 
void SetNavigationPropertyValue(RelatedEnd relatedEnd, object value); 
void RemoveNavigationPropertyValue(RelatedEnd relatedEnd, object value); 
void SetCurrentValue(EntityEntry entry, StateManagerMemberMetadata member, int ordinal, object target, object value); 
void UpdateCurrentValueRecord(object value, EntityEntry entry); 
RelationshipManager RelationshipManager { get; } 
bool OwnsRelationshipManager { get; } 
object Entity { get; } 
EntityEntry ObjectStateEntry { get; set; } 
EntityKey EntityKey { get; set; } 
ObjectContext Context { get; set; } 
MergeOption MergeOption { get; } 
Type IdentityType { get; } 
bool InitializingProxyRelatedEnds { get; set; } 
bool RequiresRelationshipChangeTracking { get; } 
} 



/// <summary> 
/// Adds an object to the object context. 
/// </summary> 
/// <param name="entitySetName">Represents the entity set name, which may optionally be qualified by the entity container name. </param><param name="entity">The <see cref="T:System.Object"/> to add.</param><exception cref="T:System.ArgumentNullException">The <paramref name="entity"/> parameter is null. -or-The <paramref name="entitySetName"/> does not qualify.</exception> 
public void AddObject(string entitySetName, object entity) 
{ 
    EntityUtil.CheckArgumentNull<object>(entity, "entity"); 
    EntityEntry existingEntry; 
    IEntityWrapper wrappedEntity = EntityWrapperFactory.WrapEntityUsingContextGettingEntry(entity, this, out existingEntry); 
    if (existingEntry == null) 
    this.MetadataWorkspace.ImplicitLoadAssemblyForType(wrappedEntity.IdentityType, (Assembly) null); 
    EntitySet entitySet; 
    bool isNoOperation; 
    this.VerifyRootForAdd(false, entitySetName, wrappedEntity, existingEntry, out entitySet, out isNoOperation); 
    if (isNoOperation) 
    return; 
    System.Data.Objects.Internal.TransactionManager transactionManager = this.ObjectStateManager.TransactionManager; 
    transactionManager.BeginAddTracking(); 
    try 
    { 
    RelationshipManager relationshipManager = wrappedEntity.RelationshipManager; 
    bool flag = true; 
    try 
    { 
     this.AddSingleObject(entitySet, wrappedEntity, "entity"); 
     flag = false; 
    } 
    finally 
    { 
     if (flag && wrappedEntity.Context == this) 
     { 
     EntityEntry entityEntry = this.ObjectStateManager.FindEntityEntry(wrappedEntity.Entity); 
     if (entityEntry != null && entityEntry.EntityKey.IsTemporary) 
     { 
      relationshipManager.NodeVisited = true; 
      RelationshipManager.RemoveRelatedEntitiesFromObjectStateManager(wrappedEntity); 
      RelatedEnd.RemoveEntityFromObjectStateManager(wrappedEntity); 
     } 
     } 
    } 
    relationshipManager.AddRelatedEntitiesToObjectStateManager(false); 
    } 
    finally 
    { 
    transactionManager.EndAddTracking(); 
    } 
} 
+0

这回答了第二部分,但第一部分呢? –

+0

默认情况下,添加已更改。该对象被引用不复制 –

+0

但我试图比较我插入传递的对象和ObjectStateManager中的对象之间的引用,它们不相同。 –