System.StackOverflowException

Posts   
1  /  2
 
    
BringerOD
User
Posts: 70
Joined: 15-Jul-2006
# Posted on: 01-Sep-2008 00:44:15   

Ok, I think I have it figured out. I was not using the same LinqMetaData instance. There was no way for you to know this without a complete zip of the solution.

The good news is I have refactored out any duplicate code. This code works great now.



   /// <summary>
        /// Gets a queryable list of contacts
        /// </summary>
        /// <returns>queryable list of contacts</returns>
        public override IQueryable<Contact> GetQueryable()
        {
            var qry = _transaction.CreateLinqProvider().Contact.Select(ContactEntityMap());
            return qry.AsQueryable();
        }

        /// <summary>
        /// ContactEntity to Contact map.
        /// </summary>
        /// <returns>a function that performs mapping between LLBL and the Modal</returns>
        public Func<ContactEntity, Contact> ContactEntityMap()
        {
            return (c => new Contact
                             {
                                 ID = c.Identifier,
                                 Created = c.Created,
                                 Modified = c.Modified,
                                 ObjectType = (EntityType) c.TypeId,
                                 FirstName = c.FirstName,
                                 LastName = c.LastName,
                                 MiddleName = c.MiddleName,
                                 Salutation = c.Salutation,
                                 Suffix = c.Suffix,
                                 Title = c.Title,
                                 Addresses = new LazyList<Address>(() => _addressRepository.GetQueryableByGuid(c.Identifier).ToList())
                             });
        }


This will load my modal from my LLBLGen entities. Also, the address colllection is loaded only when used.

Bryan

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39615
Joined: 17-Aug-2003
# Posted on: 01-Sep-2008 10:12:14   

BringerOD wrote:

Ok, I think I have it figured out. I was not using the same LinqMetaData instance. There was no way for you to know this without a complete zip of the solution.

I'm still a bit puzzled why using two different LinqMetaData objects would make a difference, as the resulting expression tree is processed with the provider set in the most outer IQueryable.

The good news is I have refactored out any duplicate code. This code works great now.



   /// <summary>
        /// Gets a queryable list of contacts
        /// </summary>
        /// <returns>queryable list of contacts</returns>
        public override IQueryable<Contact> GetQueryable()
        {
            var qry = _transaction.CreateLinqProvider().Contact.Select(ContactEntityMap());
            return qry.AsQueryable();
        }

        /// <summary>
        /// ContactEntity to Contact map.
        /// </summary>
        /// <returns>a function that performs mapping between LLBL and the Modal</returns>
        public Func<ContactEntity, Contact> ContactEntityMap()
        {
            return (c => new Contact
                             {
                                 ID = c.Identifier,
                                 Created = c.Created,
                                 Modified = c.Modified,
                                 ObjectType = (EntityType) c.TypeId,
                                 FirstName = c.FirstName,
                                 LastName = c.LastName,
                                 MiddleName = c.MiddleName,
                                 Salutation = c.Salutation,
                                 Suffix = c.Suffix,
                                 Title = c.Title,
                                 Addresses = new LazyList<Address>(() => _addressRepository.GetQueryableByGuid(c.Identifier).ToList())
                             });
        }


This will load my modal from my LLBLGen entities. Also, the address colllection is loaded only when used.
Bryan

cool! simple_smile And applied where clauses to this also work?

The LazyList is clever! simple_smile

Frans Bouma | Lead developer LLBLGen Pro
BringerOD
User
Posts: 70
Joined: 15-Jul-2006
# Posted on: 01-Sep-2008 17:01:20   

You know what, you are right, I forced it to use a new LinqMetaData and all my tests based.

Sadly, I am not aware at this moment why it is working when it did not before.

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39615
Joined: 17-Aug-2003
# Posted on: 01-Sep-2008 17:12:08   

BringerOD wrote:

You know what, you are right, I forced it to use a new LinqMetaData and all my tests based.

Sadly, I am not aware at this moment why it is working when it did not before.

Let's just say, something else was out of sync. perhaps the ormsupportclasses/linq dll ? Anyway, they pass, so case closed simple_smile

Frans Bouma | Lead developer LLBLGen Pro
BringerOD
User
Posts: 70
Joined: 15-Jul-2006
# Posted on: 01-Sep-2008 17:19:05   

Thanks for your help simple_smile

Yes applied where clauses do work.

Bryan

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39615
Joined: 17-Aug-2003
# Posted on: 03-Sep-2008 16:32:27   

In this thread: http://www.llblgen.com/tinyforum/Messages.aspx?ThreadID=14217

The same thing is tried. However, it doesn't work. Now, I tried to repro this with simple northwind code.


private Func<ProductEntity, Product> CreateProductProjector()
{
    return p=>new Product()
    {
        Name = p.ProductName,
        ProdId = p.ProductId
    };
}

// test without asserts first, to see if it even works. 
[Test]
public void GetOrdersInCustomClassWithNestedProjectionUsingProjectionFunc()
{
    using(DataAccessAdapter adapter = new DataAccessAdapter())
    {
        LinqMetaData metaData = new LinqMetaData(adapter);
        var q = from o in metaData.Order
                select new Order
                {
                    OrdId = o.OrderId,
                    RelatedCustomer = new Customer
                    {
                        CompanyNme = o.Customer.CompanyName,
                        CustId = o.Customer.CustomerId
                    },
                    Products = o.ProductCollectionViaOrderDetail.Select(CreateProductProjector()).ToList()
                };

        foreach(var v in q)
        {
        }
    }
}


public class Customer
{
    public string CustId { get; set; }
    public string CompanyNme { get; set; }
}


public class Order
{
    public int OrdId { get; set; }
    public Customer RelatedCustomer { get; set; }
    public IList<Product> Products { get; set; }
}


public class Product
{
    public int ProdId { get; set; }
    public string Name { get; set; }
}

As you can see, I've a similar Projector func creating routine. Though I get at runtime a delegate in the select method call, not something usable to evaluate (i.o.w.: nothing remotely looking like an expression tree).

Am I missing something?

Frans Bouma | Lead developer LLBLGen Pro
1  /  2