AutoMapper: UseAsDataSource StackOverflow Error

This is giving me a stackoverflow error, but only when I have a collection navigation property.

return dbSet.UseAsDataSource(mapper).For<TDTO>().AsExpandable().Where(filter).ToList();

The filter is of type Expression<Func<TDTO, bool>> Possible filter values that this happens with:


filter = {f => (True AndAlso Invoke(f => (True AndAlso Invoke(Param_0 => Convert(Param_0.Cust.CustomerNumber).ToString().Contains("123"), f)), f))} 

filter = {f => (True AndAlso Invoke(f => ((((False OrElse Invoke(Param_0 => Convert(Param_0.Name1).ToString().Contains("som"), f)) OrElse Invoke(Param_0 => Convert(Param_0.Name2).ToString().Contains("som"), f)) OrElse Invoke(Param_0 => Convert(Param_0.PaytoName1).ToString().Contains("som"), f)) OrElse Invoke(Param_0 => Convert(Param_0.PaytoName2).ToString().Contains("som"), f)), f))}

Right now my mappings are just:

cfg.CreateMap<Cust, CustDTO>().ReverseMap();
cfg.CreateMap<Customer, CustomerDTO>().ReverseMap();

Previously I could get away with this because I didn’t need the collection.

But now I have added another entity, which requires me to have that collection available in Cust. This Customers property in Cust is just an example of what is causing it.

Here are the relevant properties in the entities:

namespace-Domain:

public class Cust : IEntity   {

       [Key]
       public int CustomerID { get; set; }

       public string CustomerNumber { get; set; }
       public bool Status { get; set; } 
       public virtual ICollection<Customer> Customers { get; set; }
       } 

  public class Customer : IEntity
   {
       [Key]
       public int Id { get; set; }

       [ForeignKey("Cust")]
       public int CustomerId { get; set; }
       public virtual Cust Cust { get; set; }
       public bool Status { get; set; }
       public string Name1 { get; set; }
}

namespace-DTO:

public class CustDTO : IDTO
    {
        public int CustomerID { get; set; }
        public string CustomerNumber { get; set; }
        public bool Status { get; set; }

        public virtual ICollection<CustomerDTO> Customers { get; set; }
    }

public class CustomerDTO : IDTO
    {
        public int Id { get; set; }

        public int CustomerId { get; set; }
        public virtual CustDTO Cust { get; set; }
        public bool Status { get; set; }
        public string Name1 { get; set; }
}

Another note: I’m not sure if this is relevant, but If I remove .AsExpandable() the error changes to (depending on the filter value stated above):

 'System.ArgumentException'
Property 'namespace-Domain.Cust Cust' is not defined for type 'namespace-DTO.CustomerDTO'

or

 'System.ArgumentException'
Property 'System.String Name1' is not defined for type 'namespace-DTO.CustomerDTO'

I wrote this a while ago, and am a little fuzzy on why I needed AsExpandable(), but it seems it was required to successfully map from Entity -> DTO… as pointed out by the incorrect namespace on the Cust object in the error.

About this issue

  • Original URL
  • State: closed
  • Created 8 years ago
  • Comments: 21 (11 by maintainers)

Commits related to this issue

Most upvoted comments

To map from model to dto you need to write a select statement. If you think AutoMapper doesn’t do it well enough, how would you break the cycle?

Unless I’m missing something, the only way to break the cycle is to introduce incompatible initializations (for MaxDepth > 1; see the PR for MaxDepth 1). @AGnbrown1 If you disagree, how would the Select look like?

Looking at the code and looking at the exception more it says at the very bottom it says AutoMapper.QueryableExtensions.ProjectionExpression.To[TResult](Object parameters)

It looks like MaxDepth is only checked in ExpressionBuilder and not in all its IExpressionBinder’s which is where the Circular reference is happening.

Lol well that wasn’t necessarily a bad thing, but in LINQ I generally try and avoid it. Otherwise you need to use MaxDepth, but that can be confusing.

So your DTOs have circular references?