Returning Anonymous Types

Posts   
 
    
samspam
User
Posts: 7
Joined: 24-May-2009
# Posted on: 26-May-2009 05:09:44   

I want to return an anonymous type from a method, with the following query.


using (DataAccessAdapter adapter = new DataAccessAdapter())
            {
                LinqMetaData linq = new LinqMetaData(adapter);
                var q = from RelReqEntity in linq.ReleaseRequest
                        where RelReqEntity.ReleaseId == _releaseID

                        join AuthBy in linq.ReleaseUser
                        on RelReqEntity.AuthorisedBy equals AuthBy.UserId into j1
                        from user in j1.DefaultIfEmpty()

                        join CreateUsr in linq.ReleaseUser
                        on RelReqEntity.CreatedUser equals CreateUsr.UserId into j2
                        from user1 in j2.DefaultIfEmpty()

                        join ModUsr in linq.ReleaseUser
                        on RelReqEntity.ModifiedUser equals ModUsr.UserId into j3
                        from user2 in j3.DefaultIfEmpty()

                        join App in linq.ReleaseApplication
                        on RelReqEntity.ApplicationCodeId equals App.ApplicationCodeId into j4
                        from App1 in j4.DefaultIfEmpty()
                        select new 
                        {
                            RelReqEntity,
                            AuthBy = user.FirstName + " " + user.LastName,
                            CUsr = user1.FirstName + " " + user1.LastName,
                            MUser = user2.FirstName + " " + user2.LastName
                        };

How do I return this, besides using a foreach? (as RelReqEntity contains about 30 fields)

Is it possible to create and return a custom Entity based on "RelReqEntity" and adding the new fields AuthBy , CUsr , MUser, or is there another way?

Walaa avatar
Walaa
Support Team
Posts: 14993
Joined: 21-Aug-2005
# Posted on: 26-May-2009 10:03:35   

Is it possible to create and return a custom Entity based on "RelReqEntity" and adding the new fields AuthBy , CUsr , MUser, or is there another way?

Why don't you just add these properties to your entity.

samspam
User
Posts: 7
Joined: 24-May-2009
# Posted on: 26-May-2009 10:20:45   

Walaa wrote:

Is it possible to create and return a custom Entity based on "RelReqEntity" and adding the new fields AuthBy , CUsr , MUser, or is there another way?

Why don't you just add these properties to your entity.

I guess I could, I thought doing it programtically within this method would be best. Also I wasnt sure I should change the generated entities.

Whats the best way to add these properties to the entity?

Walaa avatar
Walaa
Support Team
Posts: 14993
Joined: 21-Aug-2005
# Posted on: 26-May-2009 10:29:00   

There are many ways, but I prefer this: Add a new file.....Use "partial" to re declare the class and then add these methods. So when you regenerate the code, your file won't be deleted or overwritten.

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39859
Joined: 17-Aug-2003
# Posted on: 26-May-2009 13:13:39   

You also can't return an anonymous type from a method in .NET, they're local to the scope they're created in .

(You can trick the compiler by using a lookalike type, but that's not really what you should. Anonymous types should stay in the scope they're created in)

Frans Bouma | Lead developer LLBLGen Pro
samspam
User
Posts: 7
Joined: 24-May-2009
# Posted on: 27-May-2009 04:56:43   

Walaa wrote:

There are many ways, but I prefer this: Add a new file.....Use "partial" to re declare the class and then add these methods. So when you regenerate the code, your file won't be deleted or overwritten.

Thanks for your help...I dont know whether I am flogging a dead horse but I am not sure how to get these properties into the ReleaseRequestEnity so the linq query populate with data.

Am I on the right track with below:

public partial class ReleaseRequestEntity : CommonEntityBase, ISerializable
    {

        
        public virtual System.String AuthBy
        {
            get { return (System.String)GetValue((int)ReleaseRequestFieldIndex.AuthBy, true); }
            set { SetValue((int)ReleaseRequestFieldIndex.AuthBy, value); }
        }


        
        public virtual System.String CUsr
        {
            get { return (System.String)GetValue((int)ReleaseRequestFieldIndex.CUsr, true); }
            set { SetValue((int)ReleaseRequestFieldIndex.CUsr, value); }
        }

        
        public virtual System.String MUser
        {
            get { return (System.String)GetValue((int)ReleaseRequestFieldIndex.MUser, true); }
            set { SetValue((int)ReleaseRequestFieldIndex.MUser, value); }
        }


        private static void SetupCustomPropertyHashtables()
        {

            Dictionary<string, string> fieldHashtable = null;
            fieldHashtable = new Dictionary<string, string>();

            _fieldsCustomProperties.Add("AuthBy", fieldHashtable);
            fieldHashtable = new Dictionary<string, string>();

            _fieldsCustomProperties.Add("CUsr", fieldHashtable);
            fieldHashtable = new Dictionary<string, string>();

            _fieldsCustomProperties.Add("MUser", fieldHashtable);
            fieldHashtable = new Dictionary<string, string>();
        

        }
Otis avatar
Otis
LLBLGen Pro Team
Posts: 39859
Joined: 17-Aug-2003
# Posted on: 27-May-2009 18:30:44   

Your projection places an entity instance into an anonymous type. We don't support that in our linq provider, as entity fetches use a different pipeline.

It's a little problematic to create a projection which creates a new entity and also your properties. So you should use prefetch paths instead: fetch the 3 related user entities with the normal user entity using 'WithPath' and remove all the joins as you don't need them anymore.

Then do:


public partial class ReleaseRequestEntity
{
    public string AuthByFullName
    { 
        get 
        {
            if(this.CreateUser==null)
            {
                return string.Empty;
            }
            // 'AuthorizedUser' is the field mapped onto ReleaseRequest -> User over AuthorizedBy -> UserId
            return this.AuthorizedUser.FirstName + " " + this.AuthorizedUser.LastName;
        }
    }
    
    // other properties the same. 
}

so you fetch the release request and the 3 related user entities.

Your query then becomes something like:

var q = (from r in linq.ReleaseRequest
         where r.ReleaseId == _releaseID
         select r)
            .WithPath(p=>p.Prefetch(r=>r.AuthorizedUser)
                    .Prefetch(r=>r.CTorUser)
                    .Prefetch(r=>r.MUser));

Frans Bouma | Lead developer LLBLGen Pro
samspam
User
Posts: 7
Joined: 24-May-2009
# Posted on: 28-May-2009 12:42:12   

Otis wrote:

so you fetch the release request and the 3 related user entities.

I seem to get the following error no matter what usings and references I have. Sorry, I am pretty new to this.

'System.Linq.IQueryable<Data.EntityClasses.ReleaseRequestEntity>' does not contain a definition for 'WithPath' and no extension method 'WithPath' accepting a ...

  using (DataAccessAdapter adapter = new DataAccessAdapter())
            {
                LinqMetaData linq = new LinqMetaData(adapter);
                var q = (from RelReq in linq.ReleaseRequest
                        where RelReq.ReleaseId == _releaseID
                        select RelReq).WithPath(p=>p.Prefetch(RelReq=>RelReq.AuthorisedBy));

            }

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39859
Joined: 17-Aug-2003
# Posted on: 28-May-2009 13:34:50   

Make sure you have a using statement at the top of the code file which refers to SD.LLBLGen.Pro.LinqSupportClasses

as this is an extension method defined by our linq provider simple_smile

Frans Bouma | Lead developer LLBLGen Pro
samspam
User
Posts: 7
Joined: 24-May-2009
# Posted on: 29-May-2009 10:42:23   

Otis wrote:

Make sure you have a using statement at the top of the code file which refers to SD.LLBLGen.Pro.LinqSupportClasses

as this is an extension method defined by our linq provider simple_smile

thanks for your help...