what is missing in my deep detach?

Discussion of open issues, suggestions and bugs regarding Entity Framework support in ADO.NET Data providers
Post Reply
adam2008
Posts: 1
Joined: Mon 11 Feb 2013 07:12

what is missing in my deep detach?

Post by adam2008 » Mon 11 Feb 2013 07:21

I try to detach an entity of type `group`.

Actucally I save it in my cache, and detach it a moment before responding the client.

On the next request I get the `group` from the cache and re-attch a new objectContext.



However I get `An entity object cannot be referenced by multiple instances of IEntityChangeTracker`


I know attach pantrate to all related entities,

But detach dosesn't. There I have to detach every related entity.


What am I missing in my detach?

**here is my entities hirarchy:**
public partial class App
{
public App()
{
this.Pairs = new HashSet<Pair>();
}

public string AppName { get; set; }
public System.Guid AppGuid { get; set; }
public string ClientAppID { get; set; }
public bool IsDeleted { get; set; }
public Nullable<System.DateTime> CreatedDate { get; set; }
public Nullable<System.DateTime> UpdatedDate { get; set; }

public virtual AppsData AppsData { get; set; }
public virtual ICollection<Pair> Pairs { get; set; }
}


public partial class AppsData
{
public System.Guid AppGuid { get; set; }
public string Url { get; set; }
public string DisplayName { get; set; }
public string AppDesc { get; set; }
public string PrivacyPolicyUrl { get; set; }
public string TermsOfUseUrl { get; set; }
public string LocalizationKey { get; set; }
public string Compatibility { get; set; }
public bool HiddenApp { get; set; }
public bool IsExperimental { get; set; }

public virtual App App { get; set; }
}

public partial class Browser
{
public Browser()
{
this.BrowserVersions = new HashSet<BrowserVersion>();
}

public int BrowserID { get; set; }
public string BrowserName { get; set; }
public string BrowserCode { get; set; }

public virtual ICollection<BrowserVersion> BrowserVersions { get; set; }
}

public partial class BrowserVersion
{
public BrowserVersion()
{
this.BrowserVerToCriterias = new HashSet<BrowserVerToCriteria>();
}

public System.Guid BrowserVersionID { get; set; }
public int BrowserID { get; set; }
public string Version { get; set; }
public System.DateTime CreatedDate { get; set; }
public System.DateTime UpdatedDate { get; set; }
public Nullable<int> Group_Id { get; set; }

public virtual Browser Browser { get; set; }
public virtual ICollection<BrowserVerToCriteria> BrowserVerToCriterias { get; set; }
}

public partial class BrowserVerToCriteria
{
public System.Guid CriteriaID { get; set; }
public System.Guid BrowserVersionID { get; set; }
public string ConditionBrowserVersion { get; set; }

public virtual BrowserVersion BrowserVersion { get; set; }
public virtual Criterion Criterion { get; set; }
}

public partial class CommonConfig
{
public int ID { get; set; }
public string NAME { get; set; }
public string VALUE { get; set; }
public System.DateTime CREATED_DATE { get; set; }
public System.DateTime UPDATED_DATE { get; set; }
public byte GROUP_ID { get; set; }
public string DESCRIPTION { get; set; }
}

public partial class Country
{
public Country()
{
this.Criteria = new HashSet<Criterion>();
this.Criteria1 = new HashSet<Criterion>();
}

public int CountryID { get; set; }
public string CountryCode { get; set; }
public string CountryName { get; set; }

public virtual ICollection<Criterion> Criteria { get; set; }
public virtual ICollection<Criterion> Criteria1 { get; set; }
}

public Criterion()
{
this.BrowserVerToCriterias = new HashSet<BrowserVerToCriteria>();
this.Countries = new HashSet<Country>();
this.CountriesExceptions = new HashSet<Country>();
this.Pairs = new HashSet<Pair>();
}

public System.Guid CriteriaID { get; set; }
public string Domains { get; set; }
public System.DateTime CreatedDate { get; set; }
public System.DateTime UpdatedDate { get; set; }
public string DomainsExclude { get; set; }

public virtual ICollection<BrowserVerToCriteria> BrowserVerToCriterias { get; set; }
public virtual ICollection<Country> Countries { get; set; }
public virtual ICollection<Country> CountriesExceptions { get; set; }
public virtual ICollection<Pair> Pairs { get; set; }
}

public partial class CTID
{
public string CTID1 { get; set; }
public string AppVersion { get; set; }
}

public partial class CtidPgPastExistence
{
public string Ctid { get; set; }
}

public partial class Group
{
public Group()
{
this.Pairs = new HashSet<Pair>();
}

public System.Guid GroupId { get; set; }
public int TestId { get; set; }
public int IdInTest { get; set; }
public bool WelcomeExperienceEnabledByDefault { get; set; }

public virtual MamConfiguration MamConfiguration { get; set; }
public virtual ICollection<Pair> Pairs { get; set; }
}

public partial class MamConfiguration
{
public MamConfiguration()
{
this.Groups = new HashSet<Group>();
this.MamConfigurationCTIDs = new HashSet<MamConfigurationCTID>();
}

public int TestID { get; set; }
public string TestName { get; set; }
public string Description { get; set; }
public int StatusId { get; set; }
public System.DateTime CreatedDate { get; set; }
public System.DateTime UpdatedDate { get; set; }
public bool IsProd { get; set; }
public int TestTraffic { get; set; }

public virtual ICollection<Group> Groups { get; set; }
public virtual MamConfigurationStatus MamConfigurationStatus { get; set; }
public virtual ICollection<MamConfigurationCTID> MamConfigurationCTIDs { get; set; }
}

public partial class MamConfigurationCTID
{
public int TestID { get; set; }
public string CTID { get; set; }

public virtual MamConfiguration MamConfiguration { get; set; }
}


public partial class MamConfigurationStatus
{
public MamConfigurationStatus()
{
this.MamConfigurations = new HashSet<MamConfiguration>();
}

public int StatusId { get; set; }
public string Status { get; set; }

public virtual ICollection<MamConfiguration> MamConfigurations { get; set; }
}

public partial class Pair
{
public Pair()
{
this.Groups = new HashSet<Group>();
}

public System.Guid PairID { get; set; }
public System.Guid CriteriaID { get; set; }
public System.Guid AppGuid { get; set; }

public virtual App App { get; set; }
public virtual Criterion Criterion { get; set; }
public virtual ICollection<Group> Groups { get; set; }
}

public partial class SettingsServicesConfig
{
public int ID { get; set; }
public string Name { get; set; }
public string URL { get; set; }
public int Interval { get; set; }
public System.DateTime UPDATED_DATE { get; set; }
public System.DateTime CREATED_DATE { get; set; }
public int GROUP_ID { get; set; }
}







**here is my detach function:**

public void Detach<T>(MaMDBEntities maMdbEntities, T item) where T : class, new()
{
switch (typeof (T).Name.ToLower())
{
case "group":
{
var group = item as Group;

if (group == null)
{
mApplicationLogger.Error(string.Format("Couldn't cast item to type 'Group'"));

throw new InvalidCastException(string.Format("Couldn't cast item to type 'Group'"));
}

DetachState(maMdbEntities, group.MamConfiguration);

foreach (var pair in group.Pairs.ToList())
{
DetachState(maMdbEntities, pair.App);

DetachState(maMdbEntities, pair.App.AppsData);

foreach (var country in pair.Criterion.Countries.ToList())
{
DetachState(maMdbEntities, country);
}

foreach (var country in pair.Criterion.CountriesExceptions.ToList())
{
DetachState(maMdbEntities, country);
}


foreach (var browserVerToCriterias in pair.Criterion.BrowserVerToCriterias.ToList())
{
DetachState(maMdbEntities, browserVerToCriterias.BrowserVersion.Browser);

DetachState(maMdbEntities, browserVerToCriterias.BrowserVersion);

DetachState(maMdbEntities, browserVerToCriterias);
}

DetachState(maMdbEntities, pair.Criterion);

DetachState(maMdbEntities, pair);

}

break;
}
}
maMdbEntities.Entry(item).State = EntityState.Detached;
}

private static void DetachState(MaMDBEntities maMdbEntities, object item)
{
maMdbEntities.Entry(item).State = EntityState.Detached;
}

Shalex
Site Admin
Posts: 9543
Joined: Thu 14 Aug 2008 12:44

Re: what is missing in my deep detach?

Post by Shalex » Mon 11 Feb 2013 17:24

1. There is not enough information for reproducing the error. Could you please send us a small complete test project?

2. Review the approach used in your project. For example:
  • use the AsNoTracking method to return the entities which are not tracked by the context
  • if you are using two separate contexts - one is for reading data from database and the second is for saving data to database - turn off change tracking for the context which is used for reading

Post Reply