Note that there are some explanatory texts on larger screens.

plurals
  1. POEntity framework uses a lot of memory
    text
    copied!<p>Here is a image from the ANTS memory profiler. It seens that there are a lot of objects hold in memory. How can I find what I am doing wrong?</p> <p><img src="https://i.stack.imgur.com/If3jJ.jpg" alt="ANTS memory profiler"></p> <pre><code>**UPDATE** </code></pre> <p>Here is my repository classes:</p> <pre><code>public class Repository&lt;T&gt; : IRepository&lt;T&gt; where T : class, IDataEntity { ObjectContext _context; IObjectSet&lt;T&gt; _objectSet; readonly string _entitySetName; readonly string[] _keyNames; private ObjectContext Context { get { if (_context == null) { _context = GetCurrentUnitOfWork&lt;EFUnitOfWork&gt;().Context; } return _context; } } private IObjectSet&lt;T&gt; ObjectSet { get { if (_objectSet == null) { _objectSet = this.Context.CreateObjectSet&lt;T&gt;(); } return _objectSet; } } public TUnitOfWork GetCurrentUnitOfWork&lt;TUnitOfWork&gt;() where TUnitOfWork : IUnitOfWork { return (TUnitOfWork)UnitOfWork.Current; } public virtual IEnumerable&lt;T&gt; GetQuery() { return ObjectSet; } public virtual IEnumerable&lt;T&gt; GetQuery(params Expression&lt;Func&lt;T, object&gt;&gt;[] includes) { return ObjectSet.IncludeMultiple(includes); } public virtual IEnumerable&lt;T&gt; GetQuery( IEnumerable&lt;Expression&lt;Func&lt;T, bool&gt;&gt;&gt; filters, Func&lt;IQueryable&lt;T&gt;, IOrderedQueryable&lt;T&gt;&gt; orderBy, IEnumerable&lt;Expression&lt;Func&lt;T, object&gt;&gt;&gt; includes) { IQueryable&lt;T&gt; _query = ObjectSet; if (filters != null) { foreach (var filter in filters) { _query = _query.Where(filter); } } if (includes != null &amp;&amp; includes.Count() &gt; 0) { _query = _query.IncludeMultiple(includes.ToArray()); } if (orderBy != null) { _query = orderBy(_query); } return _query; } public virtual IPaged&lt;T&gt; GetQuery( IEnumerable&lt;Expression&lt;Func&lt;T, bool&gt;&gt;&gt; filters, Func&lt;IQueryable&lt;T&gt;, IOrderedQueryable&lt;T&gt;&gt; orderBy, int pageNumber, int pageSize, IEnumerable&lt;Expression&lt;Func&lt;T, object&gt;&gt;&gt; includes) { IQueryable&lt;T&gt; _query = ObjectSet; if (filters != null) { foreach (var filter in filters) { _query = _query.Where(filter); } } if (orderBy != null) { _query = orderBy(_query); } IPaged&lt;T&gt; page = new Paged&lt;T&gt;(_query, pageNumber, pageSize, includes); return page; } public virtual void Insert(T entity) { this.ObjectSet.AddObject(entity); } public virtual void Delete(T entity) { if (entity is ISoftDeletable) { ((ISoftDeletable)entity).IsDeleted = true; //Update(entity); } else { this.ObjectSet.DeleteObject(entity); } } public virtual void Attach(T entity) { ObjectStateEntry entry = null; if (this.Context.ObjectStateManager.TryGetObjectStateEntry(entity, out entry) == false) { this.ObjectSet.Attach(entity); } } public virtual void Detach(T entity) { ObjectStateEntry entry = null; if (this.Context.ObjectStateManager.TryGetObjectStateEntry(entity, out entry) == true) { this.ObjectSet.Detach(entity); } } } </code></pre> <p>Now, if I have class A that holds records from table A, I also create class:</p> <pre><code>public class ARepository:BaseRepository&lt;A&gt; { // Implementation of A's queries and specific db operations } </code></pre> <p>Here is my EFUnitOfWork class:</p> <pre><code>public class EFUnitOfWork : IUnitOfWork, IDisposable { public ObjectContext Context { get; private set; } public EFUnitOfWork(ObjectContext context) { Context = context; context.ContextOptions.LazyLoadingEnabled = true; } public void Commit() { Context.SaveChanges(); } public void Dispose() { if (Context != null) { Context.Dispose(); } GC.SuppressFinalize(this); } } </code></pre> <p>And UnitOfWork class:</p> <pre><code>public static class UnitOfWork { private const string HTTPCONTEXTKEY = "MyProj.Domain.Business.Repository.HttpContext.Key"; private static IUnitOfWorkFactory _unitOfWorkFactory; private static readonly Hashtable _threads = new Hashtable(); public static void Commit() { IUnitOfWork unitOfWork = GetUnitOfWork(); if (unitOfWork != null) { unitOfWork.Commit(); } } public static IUnitOfWork Current { get { IUnitOfWork unitOfWork = GetUnitOfWork(); if (unitOfWork == null) { _unitOfWorkFactory = ObjectFactory.GetInstance&lt;IUnitOfWorkFactory&gt;(); unitOfWork = _unitOfWorkFactory.Create(); SaveUnitOfWork(unitOfWork); } return unitOfWork; } } private static IUnitOfWork GetUnitOfWork() { if (HttpContext.Current != null) { if (HttpContext.Current.Items.Contains(HTTPCONTEXTKEY)) { return (IUnitOfWork)HttpContext.Current.Items[HTTPCONTEXTKEY]; } return null; } else { Thread thread = Thread.CurrentThread; if (string.IsNullOrEmpty(thread.Name)) { thread.Name = Guid.NewGuid().ToString(); return null; } else { lock (_threads.SyncRoot) { return (IUnitOfWork)_threads[Thread.CurrentThread.Name]; } } } } private static void SaveUnitOfWork(IUnitOfWork unitOfWork) { if (HttpContext.Current != null) { HttpContext.Current.Items[HTTPCONTEXTKEY] = unitOfWork; } else { lock(_threads.SyncRoot) { _threads[Thread.CurrentThread.Name] = unitOfWork; } } } } </code></pre> <p>Here is how I use this:</p> <pre><code> public class TaskPriceRepository : BaseRepository&lt;TaskPrice&gt; { public void Set(TaskPrice entity) { TaskPrice taskPrice = GetQuery().SingleOrDefault(x =&gt; x.TaskId == entity.TaskId); if (taskPrice != null) { CommonUtils.CopyObject&lt;TaskPrice&gt;(entity, ref taskPrice); } else { this.Insert(entity); } } } public class BranchRepository : BaseRepository&lt;Branch&gt; { public IList&lt;Branch&gt; GetBranchesList(Guid companyId, long? branchId, string branchName) { return Repository.GetQuery(). Where(b =&gt; companyId == b.CompanyId). Where(b =&gt; b.IsDeleted == false). Where(b =&gt; !branchId.HasValue || b.BranchId.Equals(branchId.Value)). Where(b =&gt; branchName == null || b.BranchName.Contains(branchName)). ToList(); } } [WebMethod] public void SetTaskPrice(TaskPriceDTO taskPrice) { TaskPrice tp = taskPrice.ToEntity(); TaskPriceRepository rep = new TaskPriceRepository(); rep.Set(tp); UnitOfWork.Commit(); } [WebMethod] public IList&lt;Branch&gt; GetBranchesList() { BranchRepository rep = new BranchRepository(); return rep.GetBranchesList(m_User.UserCompany.CompanyId, null, null).ToList(); } </code></pre> <p>I hope this is enough info to help me solving the problem. Thanks.</p> <p><strong><code>UPDATE 2</code></strong><br> There is also UnitOfWorkFactory that initializes UnitOfWork:</p> <pre><code>public class UnitOfWorkFactory : IUnitOfWorkFactory { private static Func&lt;ObjectContext&gt; _objectContextDelegate; private static readonly Object _lockObject = new object(); public static void SetObjectContext(Func&lt;ObjectContext&gt; objectContextDelegate) { _objectContextDelegate = objectContextDelegate; } public IUnitOfWork Create() { ObjectContext context; lock (_lockObject) { context = _objectContextDelegate(); } return new EFUnitOfWork(context); } } </code></pre> <p>In order to use this, in the application startup I use structuremap:</p> <pre><code> ObjectFactory.Initialize(x =&gt; { x.For&lt;IUnitOfWorkFactory&gt;().Use&lt;UnitOfWorkFactory&gt;(); x.For(typeof(IRepository&lt;&gt;)).Use(typeof(Repository&lt;&gt;)); }); </code></pre>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload