1

I have a Model with a property of a value object type as following:

public class Course : AggregateRoot, ISpModel
{
    ...
    public UnsignedNumber MaximumCapacity { get; private set; }
    ...
}

with UnsignedNumber being a value object containing a short value:

public class UnsignedNumber : BaseValueObject<UnsignedNumber>
{
    public short Value { get; }
    ...
}

What I need to do is to sum all the MaximumCapacities of courses which correspond with certain conditions, but when I try to add a SumAsync(x => x.MaximumCapacity) at the end of the query, I get a syntax error the syntax error and when I try to do the same with it's value, I get a linq error in runtime.

"The LINQ expression '(int)(EntityShaperExpression: \r\n EntityType: Course\r\n ValueBufferExpression: \r\n (ProjectionBindingExpression: Outer)\r\n IsNullable: False\r\n).MaximumCapacity.Value' could not be translated. Either rewrite the query in a form that can be translated, or switch to client evaluation explicitly by inserting a call to either AsEnumerable(), AsAsyncEnumerable(), ToList(), or ToListAsync(). See https://go.microsoft.com/fwlink/?linkid=2101038 for more information."

Edit: Here's the Linq Expression that encounters the problem:

var query = _dbContext.Courses.AsQueryable();
query = query.Include(x => BunchOfIncludes(x));
var res = await query.Where(x => BunchOfClauses(x)).SumAsync(x => x.MaximumCapacity.Value);

Edit2: the classes mentioned above:

public abstract class AggregateRoot : Entity
{
    private readonly List<IDomainEvent> _events;
    protected AggregateRoot() => _events = new List<IDomainEvent>();
    public AggregateRoot(IEnumerable<IDomainEvent> events)
    {
        if (events == null) return;
        foreach (var @event in events)
            ((dynamic)this).On((dynamic)@event);
    }
    protected void AddEvent(IDomainEvent @event) => _events.Add(@event);
    public IEnumerable<IDomainEvent> GetEvents() => _events.AsEnumerable();
    public void ClearEvents() => _events.Clear();
}
public interface ISpModel
{
}
public abstract class BaseValueObject<TValueObject> : IEquatable<TValueObject>
        where TValueObject : BaseValueObject<TValueObject>
{
...
    public static bool operator ==(BaseValueObject<TValueObject> right, BaseValueObject<TValueObject> left)
    {
        if (right is null && left is null)
            return true;
        if (right is null || left is null)
            return false;
        return right.Equals(left);
    }
...
}
  • Please add the Linq expression. – Fildor Jun 07 '21 at 08:38
  • @Fildor check out the edited version – Sein Gerivani Jun 07 '21 at 12:11
  • I think that Sum-Overload is not supported: https://learn.microsoft.com/en-us/dotnet/framework/data/adonet/ef/language-reference/supported-and-unsupported-linq-methods-linq-to-entities#aggregate-methods ... maybe if you ... `var res = await query.Where(x => BunchOfClauses(x)).Select(x => x.MaximumCapacity).SumAsync(x => x.Value);` ? – Fildor Jun 07 '21 at 12:39
  • @Fildor just double checked. didn't work – Sein Gerivani Jun 07 '21 at 12:48
  • Hi @SeinGerivani, what is the version of ef core? If the version is beyond 3.0, the error message is caused by implicit client evaluation has been disabled in EF Core 3. I think you need provide `AggregateRoot`,`ISpModel` and `BaseValueObject` to help reproduce the issue. – Rena Jun 08 '21 at 08:21
  • @Rena the EF core is indeed beyond 3 (3.1.4 to be precise). I'll add the classes and the interfaces you've asked but those are just the start of the inheritance chain. – Sein Gerivani Jun 08 '21 at 11:39
  • @SeinGerivani Have you tried to write the query without the helper methods `BunchOfIncludes(x)` and `BunchOfClauses(x)`? I mean you replace these methods with what inside them. – Ali Jun 26 '21 at 11:37
  • @Ali those are not helper methods. I just hid the business for simplification. – Sein Gerivani Jun 27 '21 at 09:02
  • @SeinGerivani I see. Yes, try to write what is inside directly in the `Include` and the `Where`. For example, let us say `BunchOfClauses(x)` contains something like `Condition == true`, try to write it in the `Where` filter like `.Where(x => x.Condistion== true)`. – Ali Jun 27 '21 at 19:20
  • @Ali That is how the actual code is like – Sein Gerivani Jun 28 '21 at 11:48
  • @SeinGerivani That's good. Now try this `modelBuilder.Entity().OwnsOne(p => p.MaximumCapacity, a => a.Property(x => x.Value).HasColumnName("MaximumCapacity"));` in `OnModelCreating` in your `DbContext`. Note the `.HasColumnName("MaximumCapacity")` is column name in the database. – Ali Jun 28 '21 at 15:44

0 Answers0