LINQ projection with static enum.

Posts   
 
    
Brandt
User
Posts: 142
Joined: 04-Apr-2007
# Posted on: 09-Feb-2009 15:35:57   

Just a quick question

Can you explain why I can't use a static enum assignment in the projection of a linq query? Is there a way around it?

The AssignmentType in this query is an enum and the query throws and ormexception.


var serverContactAssignments = (from sc in this._contactRepository.LinqDataContext.ServerContact
                                            
                                            where sc.ContactId == contact.ContactId
                                            select new AssignmentDataView()
            {
                AssignmentId = sc.ServerId.ToString(),
                AssignmentName = sc.Servers.Srvnm,
                AssignmentType = AssignmentType.Server,
                ContactId = sc.ContactId,
                RoleTypeName = sc.RoleType.Name,
                Note = sc.Note
            }).ToArray();

]

The AssignmentType in this query is a string and this one works properly.


var serverContactAssignments = (from sc in this._contactRepository.LinqDataContext.ServerContact
                                            
                                            where sc.ContactId == contact.ContactId
                                            select new AssignmentDataView()
            {
                AssignmentId = sc.ServerId.ToString(),
                AssignmentName = sc.Servers.Srvnm,
                AssignmentType = AssignmentType.Server.ToString(),
                ContactId = sc.ContactId,
                RoleTypeName = sc.RoleType.Name,
                Note = sc.Note
            }).ToArray();

]
Otis avatar
Otis
LLBLGen Pro Team
Posts: 39614
Joined: 17-Aug-2003
# Posted on: 09-Feb-2009 17:01:27   

which exception, stacktrace? What's the runtime lib build nr?

Frans Bouma | Lead developer LLBLGen Pro
Brandt
User
Posts: 142
Joined: 04-Apr-2007
# Posted on: 09-Feb-2009 17:09:54   

Otis wrote:

which exception, stacktrace? What's the runtime lib build nr?

Sorry I thought it was a known limitation. LinqSupportClasses - 2.6.09.0116; ORM = 2.6.08.1211



Test method InfrastructureCentral.Tests.ContactServiceTest.ContactService_GetAssignmentsForUser threw exception:  System.InvalidCastException: Invalid cast from 'System.String' to 'InfrastructureCentral.Core.Contacts.AssignmentType'..


System.Convert.DefaultToType(IConvertible value, Type targetType, IFormatProvider provider)
System.String.System.IConvertible.ToType(Type type, IFormatProvider provider)
System.Convert.ChangeType(Object value, Type conversionType, IFormatProvider provider)
System.Convert.ChangeType(Object value, Type conversionType)
lambda_method(ExecutionScope , Object[] , Int32[] )
AddRowToResults(IList projectors, Object[] rawProjectionResult)
SD.LLBLGen.Pro.ORMSupportClasses.IGeneralDataProjector.AddProjectionResultToContainer(List`1 valueProjectors, Object[] rawProjectionResult)
SD.LLBLGen.Pro.ORMSupportClasses.ProjectionUtils.FetchProjectionFromReader(List`1 valueProjectors, IGeneralDataProjector projector, IDataReader datasource, Int32 maxNumberOfItemsToReturn, Int32 pageNumber, Int32 pageSize, Boolean clientSideLimitation, Boolean clientSideDistinctFiltering, Boolean clientSidePaging, UniqueList`1 stringCache, Dictionary`2 typeConvertersToRun)
SD.LLBLGen.Pro.ORMSupportClasses.DataAccessAdapterBase.FetchProjection(List`1 valueProjectors, IGeneralDataProjector projector, IRetrievalQuery queryToExecute, Dictionary`2 typeConvertersToRun)
SD.LLBLGen.Pro.ORMSupportClasses.DataAccessAdapterBase.FetchProjection(List`1 valueProjectors, IGeneralDataProjector projector, IEntityFields2 fields, IRelationPredicateBucket filter, Int32 maxNumberOfItemsToReturn, ISortExpression sortClauses, IGroupByCollection groupByClause, Boolean allowDuplicates, Int32 pageNumber, Int32 pageSize)
SD.LLBLGen.Pro.LinqSupportClasses.LLBLGenProProvider2.ExecuteValueListProjection(QueryExpression toExecute)
SD.LLBLGen.Pro.LinqSupportClasses.LLBLGenProProviderBase.ExecuteExpression(Expression handledExpression)
SD.LLBLGen.Pro.LinqSupportClasses.LLBLGenProProviderBase.Execute(Expression expression)
SD.LLBLGen.Pro.LinqSupportClasses.LLBLGenProProviderBase.System.Linq.IQueryProvider.Execute(Expression expression)
Execute()
GetEnumerator()
ctor(IEnumerable`1 source)
System.Linq.Enumerable.ToArray[TSource](IEnumerable`1 source)
InfrastructureCentral.Core.Contacts.ContactService.GetAssignmentDataViewForContact(ContactEntity contact) in C:\Users\hbb9745\Documents\Visual Studio 2008\Projects\InfrastructureCentral\ICv1\Modules\InfrastructureCentral.Core\Contacts\ContactService.cs: line 51
InfrastructureCentral.Tests.ContactServiceTest.ContactService_GetAssignmentsForUser() in C:\Users\hbb9745\Documents\Visual Studio 2008\Projects\InfrastructureCentral\ICv1\InfrastructureCentral.Tests\ContactServiceTest.cs: line 105


Otis avatar
Otis
LLBLGen Pro Team
Posts: 39614
Joined: 17-Aug-2003
# Posted on: 09-Feb-2009 17:44:58   

And the .Server field is an int field in the db and you use a type converter to convert it to an enum I presume? (this so I can setup a reprocase) ?

Frans Bouma | Lead developer LLBLGen Pro
Brandt
User
Posts: 142
Joined: 04-Apr-2007
# Posted on: 09-Feb-2009 17:54:17   

Otis wrote:

And the .Server field is an int field in the db and you use a type converter to convert it to an enum I presume? (this so I can setup a reprocase) ?

It is not being converted from a field in the database. It is a constant that is thrown into the query so I can tell where an assignment came from when i union the different assignments together.



    public enum AssignmentType : int
    {
        Application = 1,
        Carrier,
        Network,
        Site,
        Server
        
    
    }


    public class AssignmentDataView
    {
        public Guid ContactId { get; internal set; }
        public AssignmentType AssignmentType { get; internal set; }
        public string AssignmentName { get; internal set; }
        public string AssignmentId { get; internal set; }
        public string  RoleTypeName { get; internal set; }
        public string Note { get; internal set; }
    }


var serverContactAssignments = (from sc in this._contactRepository.LinqDataContext.ServerContact
                                            
                                            where sc.ContactId == contact.ContactId
                                            select new AssignmentDataView()
            {
                AssignmentId = sc.ServerId.ToString(),
                AssignmentName = sc.Servers.Srvnm,
                AssignmentType = AssignmentType.Server,
                ContactId = sc.ContactId,
                RoleTypeName = sc.RoleType.Name,
                Note = sc.Note
            }).ToArray();

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39614
Joined: 17-Aug-2003
# Posted on: 09-Feb-2009 18:27:56   

aha! ok, that will make me able to repro it and look for a solution. I'm not sure if this will be possible, though, as 'enum' isn't really a type available in the expression tree, but I'll try.

Frans Bouma | Lead developer LLBLGen Pro
Otis avatar
Otis
LLBLGen Pro Team
Posts: 39614
Joined: 17-Aug-2003
# Posted on: 10-Feb-2009 11:46:51   

See attached dll. I've added more robust handling of constants in projections: they're now no longer passed as value to the query if that's not possible and the constant value itself is simply set by the compiled lambda so no conversions anymore. THis also allows for more complex constants (i.e. local object variables) to be set in the projection without the necessity of a local method.

Frans Bouma | Lead developer LLBLGen Pro