views:

74

answers:

3

Hi All,

I have been working away for EF4 and got a lot of stuff done and its working really nicely, the one problem I do have is: Context.CreateQuery returns correctly, but it is also loading ALL its related entities too!?

Which is going to cause massive issues once the DB actually has real data in there.

Any ideas on how to stop it from loading all the related entities?

Here is snippet of what I have:

The original call:

public ObjectNameHere GetById(Guid id)
    {
        return Query(p => p.Id == id).SingleOrDefault();
    }

The Provider Base

private static Type GetBaseType(Type type)
    {
        var baseType = type.BaseType;
        if (baseType != null && baseType != typeof(EntityObject))
        {
            return GetBaseType(type.BaseType);
        }
        return type;
    }

    private static bool HasBaseType(Type type, out Type baseType)
    {
        var originalType = type.GetType();
        baseType = GetBaseType(type);
        return baseType != originalType;
    }

    private IQueryable<T> CreateQuery<T>()
    {
        Type baseType;
        return HasBaseType(typeof(T), out baseType)
                   ? Context.CreateQuery<T>(ProviderHelper.GetEntitySetName(Context, baseType.Name)).OfType<T>()
                   : Context.CreateQuery<T>(ProviderHelper.GetEntitySetName(Context, baseType.Name));
    }

The Provider Helper

    public static string GetChildTypeNames(Type[] childTypes)
    {
        var context = ContextProvider.Context;

        var childNames = new StringBuilder();

        for (var i = 0; i < childTypes.Count(); i++)
        {
            childNames.Append(GetEntitySetName(context,childTypes[i].Name));

            if (i != childTypes.Count()) { childNames.Append("."); }
        }
        return childNames.ToString();
    }

    public static string GetEntitySetName(ObjectContext context, string entityTypeName)
    {

        var container = context.MetadataWorkspace.GetEntityContainer(context.DefaultContainerName, DataSpace.CSpace);
        return (from meta in container.BaseEntitySets
                                where meta.ElementType.Name == entityTypeName
                                select meta.Name).FirstOrDefault();
    }
+1  A: 

have a look here: http://thedatafarm.com/blog/data-access/a-look-at-lazy-loading-in-ef4/

devnull
A: 

James, I know you solved it dude, but did you also try to see if you could use the partial selection methods (I think there in EF) such as Skip & Take.

I have to admit, I often forget about Lazy loading, but in the long run it's never really an issue beacuse I never pull more from the DB than I need to.

Just a thought....

I'm more of an L2S person....

heh...

shawty
A: 

Thanks for all the replies, I got it working by including the line:

Context.ContextOptions.LazyLoadingEnabled = false;

in the CreateQuery method in the base class, this worked, (I had tried this before I'm 80% sure)

But oh well :)

JamesStuddart
that's what is in the link :)
devnull
Yeah I know, the article is a little out of date as it refers to DeferredLoadingEnabled where as it is LazyLoadingEnabled I swear I had put that in there before and it didnt work, but never mind, thanks for your help, I will mark you as the answer, but could you do an edit to explain the difference, for anyone else who finds this post? Cheers.
JamesStuddart