Take the 2-minute tour ×
Stack Overflow is a question and answer site for professional and enthusiast programmers. It's 100% free, no registration required.

ITNOA

I have a entity like :

public class Doctor : User
{
    public Doctor(string userName, string firstName, string lastName,
        string mobileNumber, string email, Sexes sex, Role myRole, DoctorExpertises expertise)
        : base(userName, firstName, lastName, mobileNumber, email, sex, myRole)
    {
        this.Expertise = expertise;
        this.Results = new List<Result>();
    }

    private Doctor()
    {
        this.Results = new List<Result>();
    }

    public void AddResult(Result result)
    {
        this.Results.Add(result);
    }

    public DoctorExpertises Expertise { get; private set; }

    private ICollection<Result> results;

    public virtual ICollection<Result> Results
    {
        get { return results; }
        private set { results = value; }
    }
}

and I have typical repository like:

    public abstract class RepositoryBase<T> where T : class
    {
        private DbContext dataContext;
        protected readonly IDbSet<T> dbset;

        protected RepositoryBase(IDatabaseFactory databaseFactory)
        {
            DatabaseFactory = databaseFactory;
            dbset = DataContext.Set<T>();
        }

        protected IDatabaseFactory DatabaseFactory
        {
            get;
            private set;
        }

        protected DbContext DataContext
        {
            get { return dataContext ?? (dataContext = DatabaseFactory.Get()); }
        }
        public virtual void Add(T entity)
        {
            dbset.Add(entity);
        }
        public virtual void Update(T entity)
        {
            dbset.Attach(entity);
            dataContext.Entry(entity).State = EntityState.Modified;
        }
        public virtual void Delete(T entity)
        {
            dbset.Remove(entity);
        }
        public virtual void Delete(Expression<Func<T, bool>> where)
        {
            IEnumerable<T> objects = dbset.Where<T>(where).AsEnumerable();
            foreach (T obj in objects)
                dbset.Remove(obj);
        }
        public virtual T GetById(long id)
        {
            return dbset.Find(id);
        }
        public virtual T GetById(string id)
        {
            return dbset.Find(id);
        }
        public virtual IEnumerable<T> GetAll()
        {
            return dbset.ToList();
        }
        public virtual IEnumerable<T> GetMany(Expression<Func<T, bool>> where)
        {
            return dbset.Where(where).ToList();
        }
        public T Get(Expression<Func<T, bool>> where)
        {
            return dbset.Where(where).FirstOrDefault<T>();
        }
}

and I want lazy load one result from doctor with below test code:

[TestMethod]
public void TestShouldLoadPropertyIfLazyLoaded()
{
    // Act
    Doctor doctor = this.userRepository.Get(u => u.UserName == "soroosh") as Doctor;
    Result result = doctor.Results.FirstOrDefault();

    // Asserts
    Assert.IsNotNull(doctor);
    Assert.IsNotNull(result);
}

Unfortunately it doesn’t work correctly doctor is not null but result is null.

If I use eager loading with include method it loads correctly but I want to use lazy loading definitely.

I have seen this question and other questions like this but non of them wasn't useful because all of them use eager loading to solve problem. eager loading is not suitable for us because in my main problem seems eager loading is not possible.

what should I do?

share|improve this question
    
I'm sorry but I didn't understand what did you said. I say again doctor is not null. thank you :) –  sorosh_sabz Nov 15 '13 at 15:33
    
OK I misunderstood You - sorry for that ;) I deleted the comment ;) Maybe You could try the following: Result result = doctor.Results.ToList().FirstOrDefault(); btw You should conssider splitting this into two separate tests ;) –  Przemek Walendowski Nov 15 '13 at 15:45
    
Oh and where does userRepository come from? Are You hiting the database? –  Przemek Walendowski Nov 15 '13 at 15:51
    
in initialize method I wrote some code like : this.userRepository = new UserRepository(this.databaseFactory); UserRepository is derived class from BaseRepository. –  sorosh_sabz Nov 15 '13 at 17:44
    
Why would you need lazy loading? Are you sure Result isn't another AR? –  JefClaes Nov 15 '13 at 18:12

2 Answers 2

up vote 0 down vote accepted

This should just work, people including myself do this daily and it works. I see two possible culprits:

  • the dbcontext factory could possibly create a context where lazy loading is disabled
  • the setter of your Records property is private and the generated proxy entity could just not handle it properly. Just change it to public.

Check both, focus on the second.

share|improve this answer
1  
I would suggest going with protected rather than public, because lazy-loaded properties probably shouldn't have setters stackoverflow.com/a/14774042/150342. Then I'd add a backing field to avoid the "virtual call in constructor" code smell –  Colin Nov 18 '13 at 11:39

I reckon if you fully define your aggregate boundaries you don't really need to worry about this - you can always eagerly load when loading entities to perform domain operations because your relationships shouldn't cross aggregate boundaries. Your repository should therefore only be able to load and save a single aggregate of a given type, so that the behaviour on that aggregate can be invoked.

Don't get me wrong, you might still want to query your database to put data on the UI etc, but you could just use a simple tool like Linq to SQL, Dapper etc and whack the data straight out of the DB into the UI, skipping all the ORM eager/lazy loading nonsense.

share|improve this answer
    
Whacking the data directly from the database into the ui sounds like something that should be avoided at any cost if your code is to survive longer that the first demo. Orm could be nonsene but a properly layered and testable code begs for at least one layer of abstraction behind these two. –  Wiktor Zychla Nov 16 '13 at 22:47
    
What problem is that layer of abstraction trying to solve? And how would tech like EF database-first, L2S or Dapper not be that layer of abstraction? You should be spending effort where it counts - on your domain logic and the invariants and business rules within. That's where the bulk of your tests should be. There's little point testing that you're able to read from a database, and really, how often are you likely to switch to a new rdbms anyway? I'm not saying write awful code with no exception handling etc, it should still be Clean Code, just it's not where the goal of a DDD app lies. –  Neil Barnwell Nov 17 '13 at 9:34

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.