locked
Entity Framework 4.0 ESql Problem with Schema not loaded RRS feed

  • Question

  • I would really appreciate any help with this matter.

    I have a class that I use as my base class for my models in entity framework 4.0 and most of it works fine except for one thing. So here it is:

    Class Hierarchy:

    • ModelXXX inherits from ModelBase
    • ModelBase inherits from ObjectContext

    In ModelBase, I have the following method which purpose is to return the count of a dynamic query. The query is generated in eSql and I use the metadata of the schema to generate the query.

    public int GetCountByQueryObject(ConditionEFQueryBase queryObject, string baseEntityName, ObjectContext context)
    {
         IList<ObjectParameter> parameters = new List<ObjectParameter>();
         string eSql = CountQueryStringBuilder(baseEntityName, queryObject, parameters);
         var result = context.CreateQuery<int>(eSql, parameters.ToArray());
         return result.ToList().FirstOrDefault();
    }
    

    CountQueryStringBuilder is taking my queryObject and generate eSql based on the metadata of the schema, which works fine. But when I execute the query, I get the following exception:

    An exception occured during the execution of the method :: 
    RequestFrameworkService.TaskGetRequestCount, Exception 'RequestStateId' is not a member of 
    type 'RequestFramework.Models.Shared.RequestBase' in the currently loaded schemas. Near 
    simple identifier, line 2, column 5 
    

    The eSql being generated in this case is:

    "SELECT VALUE COUNT(0) FROM (SELECT VALUE al0  FROM Container.RequestBases AS al0  WHERE (\r\nal0.RequestStateId = @p0\r\n AND al0.RequestDefinitionID = @p1\r\n))"
    

    I have other places in my application where I use the same technique to generate the eSql (without the count part) and that works fine.

    Here is the interesting part:

    1. If I remove the WHERE clause, it works fine
    2. If I do a quickwatch on context.CreateQuery(eSql, parameters.ToArray()) and start expanding the base classes (such as Context and a few others), and then I continue the execution of the code, then it works.

    So it looks to me like that EF is in an unknown state and can't generate the proper query from my eSql until "something" is being loaded in memory.

    I tried forcing loading the metadata from the Assembly with

    context.MetadataWorkspace.LoadFromAssembly(Assembly.GetExecutingAssembly());
    context.MetadataWorkspace.LoadFromAssembly(Assembly.GetCallingAssembly());
    

    But that didn't make any difference.

    I would appreciate any feedback and things to try. I tried a lot of different things already like playing around with the query itself (but since it works when tampering with the object in quickwatch, I don't think there is much more to investigate with the query itself).

    Sorry for the long post and thanks in advance for the help

    Tuesday, November 8, 2011 5:21 PM

All replies

  • Hi JS,

    Welcome!
    We will do some more pending research  about your problem and come back as soon as possible, Thanks for understanding.
    Have a nice day.


    Alan Chen[MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    Wednesday, November 9, 2011 8:48 AM
  • Thanks,

    Patiently waiting for an answer on this. I posted this of Stackoverflow in August. Fortunately, I had other stuff to work on but that is coming back on the table to be looked at again.

     

    JS 

    Thursday, November 10, 2011 1:34 AM
  • Hi JS,

    I think you can try the following code to force load the metadata from the assembly:

    private

    TObjectContext entities = new TObjectContext();

    public
    SomeClassToUseEntities()
    {
    entities.MetadataWorkspace.LoadFromAssembly(System.Reflection.
    Assembly.GetAssembly(entities.GetType()));
    }


    Have a nice day.


    Alan Chen[MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    Thursday, November 10, 2011 7:20 AM
  • Hi Alan,

    Unfortunately, your suggestion doesn't resolve the problem. To be honest with you, I didn't think it would work as this is very similar to what I've already tried.

    Thanks anyway. Awaiting other possible things to try

     

    Edit: When I open up the quick watch, the only way I can make this work is when I expand the context, then I look at my EntitySet RequestBases and expand it so that all objects are loaded in memory. I would hope this is not a solution to explore as I would expect the query to be fully executed on the SQL Server.

     

    JS


    • Edited by JS Cote Friday, November 11, 2011 1:35 AM
    Friday, November 11, 2011 1:31 AM
  • you should include the generated XXX.objectlayer.cs file.

    You can refer this link: http://mtaulty.com/CommunityServer/blogs/mike_taultys_blog/archive/2007/08/27/9646.aspx

    you don't have an O-space to query against so it fails.


    I am fish.
    Friday, November 11, 2011 9:21 AM
  • Thanks for the info,

     

    I explored this before and I didn't have any success. First, I'm using POCO and I had to generate the file myself since it didn't exist. Second, how can we explain that other queries that don't do a count are working when I don't load the objectlayer file?

    Maybe the O-Space gets loaded with the other type of queries but not with the count query? and maybe when I debug and expand on the quick watch, it forces to load the O-Space from the currently loaded context.

    If it is the case, I would really like to know how I can force the O-Space to be loaded from the context (as it should be within the context already!).

    I'll go "fishing" with your advise :)

    JS

    Friday, November 11, 2011 4:33 PM
  • I tried to force loading the OSpace with the following line of code

     

    context.MetadataWorkspace.GetItems(DataSpace.OSpace);
    but realized that it was already loaded when I inspect the MetadataWorkspace so it doesn't seem it comes from OSpace not being loaded

    Thanks

     

    Edit: It seems that OSpace is loaded, but not entirely. I don't see my types being loaded.  Adding the following line is not helping

    context.MetadataWorkspace.LoadFromAssembly(Assembly.GetAssembly(context.GetType()));
    

    • Edited by JS Cote Friday, November 11, 2011 5:06 PM
    Friday, November 11, 2011 5:02 PM
  • I'm not sure if the problem relates to your design, you can try to test in common scenario as the link.


    I am fish.
    Monday, November 14, 2011 3:46 AM
  • Thanks Fish,

    I think my next option is to try to move around some code. I have a feeling that it relates with trying to do the ESQL within a base class. My other queries, which are also ESQL, are working in a more specific class. Since what I was trying to achieve was common behavior, it made sense to put it in the base class.

    I'm also using partial classes to define my POCOs and the partial classes are in a different assembly, which may also be part of the problem (but again, I don't know why it would be a problem only with the count query).

    In summary, I still have a few things to try, but would still like to see what MSFT has to say about all this.

    Tuesday, November 15, 2011 12:02 AM