GetQueryableForEntity returns null

Posts   
 
    
rboarman
User
Posts: 83
Joined: 01-Feb-2005
# Posted on: 14-Feb-2010 03:05:49   

Hello,

I have the following method that I am using as a wrapper to access data:

public IQueryable<T> Get<T>() where T : CommonEntityBase
{
    using (var adapter = new DBAdapter())
    {
        var metaData = new LinqMetaData(adapter);
        var dataSource = metaData.GetQueryableForEntity((int)Enum.Parse(typeof(EntityType), typeof(T).Name)) as DataSource2<T>;
        return from data in dataSource
               select data;
    }
}

The issue is that dataSource is null when the query is evaluated which throws an exception.

I verified that the GetQueryableForEntity is correctly returning the right DataSource2. However, when I look at the dataSource variable it is null.

Why would the method return the correct result and yet the receiving variable remain null?

I am using the latest 2.6 code.

Thank you,

Rick

daelmo avatar
daelmo
Support Team
Posts: 8245
Joined: 28-Nov-2005
# Posted on: 14-Feb-2010 19:28:19   

Hi Rick,

I think the problem is not that the datasource variable is null (I confirm this with a test). The problem is that you are using certain DataAccessAdapter to initialize your metaData, but after the method returns value, the adapter is disposed (get out of context). So you better return only the IQueryable and inject the adapter later. Example:

public static IQueryable<T> Get<T>() where T : CommonEntityBase
{           
    var metaData = new LinqMetaData();
    var dataSource = metaData.GetQueryableForEntity((int)Enum.Parse(typeof(EntityType), typeof(T).Name)) as DataSource2<T>;
    return from data in dataSource
           select data;         
}

And the usage:

var q = Get<CustomersEntity>();

using (DataAccessAdapter adapter = new DataAccessAdapter())
{
    ((LLBLGenProProvider2)((IQueryable)q).Provider).AdapterToUse = adapter;
    var results = q.ToList();
}  

That should work wink

David Elizondo | LLBLGen Support Team
rboarman
User
Posts: 83
Joined: 01-Feb-2005
# Posted on: 14-Feb-2010 20:14:31   

Thank you for answering. However, I think there is still an issue.


1: public IQueryable<T> Get<T>() where T : CommonEntityBase
2: {
3:   using (var adapter = new DBAdapter())
4:  {
5:       var metaData = new LinqMetaData(adapter);
6:       var dataSource = metaData.GetQueryableForEntity((int)Enum.Parse(typeof(EntityType), typeof(T).Name)) as DataSource2<T>;
7:       return from data in dataSource
8:            select data;
9:  }
10: }

In the above code, line 6 calls GetQueryableForEntity which is returning the correct value. However, the contents of dataSource is null and is not being assigned the results of the GetQueryableForEntity call.

I tried this variation based on your observation of the using statement going out of context:


1: public IQueryable<T> Get<T>() where T : CommonEntityBase
2: {
3:   var adapter = new DBAdapter();
4:   var metaData = new LinqMetaData(adapter);
5:   var dataSource = metaData.GetQueryableForEntity((int)Enum.Parse(typeof(EntityType), typeof(T).Name)) as DataSource2<T>;
6:   var result =  from data in dataSource
           select data;
7:   return result;
8: }

In this example, without a using statement, line 6 is failing due to the dataSource being null. GetQueryableForEntity is returning a value but dataSource remains null.

Perhaps the "as DataSource2<T>" on line 5 is broken somehow?

Rick

daelmo avatar
daelmo
Support Team
Posts: 8245
Joined: 28-Nov-2005
# Posted on: 15-Feb-2010 05:48:29   

Weird,

I can't reproduce that with the latest runtime library version. Could be possible you make a tiny repro solution that shows your issue and attach it to this thread? (only you generated code and some ConsoleApp or TestApp with repro code, and your lgp, without binaries, zipped).

David Elizondo | LLBLGen Support Team
rboarman
User
Posts: 83
Joined: 01-Feb-2005
# Posted on: 15-Feb-2010 18:53:47   

A test project that exhibits the issue is attached.

Rick

daelmo avatar
daelmo
Support Team
Posts: 8245
Joined: 28-Nov-2005
# Posted on: 16-Feb-2010 05:06:12   

Hi Rick. Thanks for the repro solution (btw, next time please don't include any dll/bin/etc files, just code).

Now, I see what is happening: you generated code using TwoClasses preset. That creates a second entity that inherits from the original. For instance UserEntity and MyUserEntity, those are located on your \EntitySubClasses folder.

So this code:

metaData.GetQueryableForEntity((int)Enum.Parse(typeof(EntityType), typeof(T).Name))

actually returns an instance of

DataSource2<MyUsersEntity>

, because that is specified in the LinqMetaData class because those are the entities you work on at the end (where your custom logic is placed). Later you cast that to DataSource2<UsersEntity> which is not defined as a valid datasource in the LinqMetaData.

So, before go on, an advice is that if you are not really using the TwoClasses preset benefit, just use the normal preset that generates one class. You still can add custom code in partial classes.

Now, the next code snippet fixes the problem. Basically you ask for an IQueriable<MyUserEntity> and when you call GetQueryableForEntity use its parent (UserEntity). This is the only way as your code is pretty generic.

public static IQueryable<T> Get<T>() where T : CommonEntityBase
{
    var adapter = new GameDBAdapter();
    var metaData = new LinqMetaData(adapter);
    var dataSource = metaData.GetQueryableForEntity((int)Enum.Parse(typeof(EntityType), typeof(T).BaseType.Name)) as DataSource2<T>;
    var result = from data in dataSource
                 select data;
    return result;
}

static void Main(string[] args)
{
    var foo = Get<MyUsersEntity>();
}

Hope helpful wink

David Elizondo | LLBLGen Support Team
rboarman
User
Posts: 83
Joined: 01-Feb-2005
# Posted on: 16-Feb-2010 17:56:04   

Switching the preset to General2008 fixed the problem. I don't think I picked TwoClasses on purpose. It must have been the default for a new project.

Thank you for your time. You guys are the best.

Rick

MTrinder
User
Posts: 1461
Joined: 08-Oct-2008
# Posted on: 16-Feb-2010 22:11:48   

No problem, always happy to help.

Matt