0

I want to use extension methods for selecting from tables so I don't have to keep entering the fields. The problem is that when I use select directly everything is fine, but when I use the extension method, I get all sorts of errors on runtime.

This is my Media entity:

[Table("Media")]
public class MediaEntity : BaseEntity 
{
    [StringLength(500)]
    public string? FileName { get; set; }

    [StringLength(500)]
    public string? UseCase { get; set; }

    [StringLength(500)]
    public string? Link { get; set; }

    [StringLength(500)]
    public string? Title { get; set; }

    [StringLength(500)]
    public string? Size { get; set; }

    [StringLength(500)]
    public string? Time { get; set; }

    [StringLength(500)]
    public string? Artist { get; set; }

    [StringLength(500)]
    public string? Album { get; set; }
}

Here is my MediaReadDto:

public class MediaReadDto : BaseEntity 
{
        public string? FileName { get; set; }
        public string? UseCase { get; set; }
        public string? Link { get; set; }
        public string? Title { get; set; }
        public string? Size { get; set; }
        public string? Time { get; set; }
        public string? Artist { get; set; }
        public string? Album { get; set; }
}

And here is my select extension method:

public static class MediaEntityExtension 
{
    public static IEnumerable<MediaReadDto> MapContentReadDto(this IEnumerable<MediaEntity> e) 
    {
        return e.Select(y => new MediaReadDto 
                                 {
                                     Link = y.Link,
                                     UseCase = y.UseCase,
                                     Album = y.Album,
                                     Artist = y.Artist,
                                     Size = y.Size,
                                     Time = y.Time,
                                     Title = y.Title,
                                     FileName = y.FileName
                                 });
    }
}

And this is where I use my extension method:

e.Select(x => new ContentReadDto {
            Id = x.Id,
            Title = x.Title,
            Type = x.Type,
            UseCase = x.UseCase,
            Media = x.Media!.MapContentReadDto()
        })

The errors I get:

System.ArgumentException: GenericArguments[1], 'System.Collections.Generic.IEnumerable1[Utilities_aspnet.Entities.MediaEntity]', on 'TCollection InitializeSplitCollection[TElement,TCollection](Int32, Microsoft.EntityFrameworkCore.Query.QueryContext, System.Data.Common.DbDataReader, Microsoft.EntityFrameworkCore.Query.Internal.SplitQueryResultCoordinator, System.Func3[Microsoft.EntityFrameworkCore.Query.QueryContext,System.Data.Common.DbDataReader,System.Object[]], Microsoft.EntityFrameworkCore.Metadata.IClrCollectionAccessor)' violates the constraint of type 'TCollection'.

Daniel A. White
  • 187,200
  • 47
  • 362
  • 445
SinaMN75
  • 6,742
  • 5
  • 28
  • 56
  • 1
    don't use `IEnumerable` here - use `IQueryable` – Daniel A. White Apr 14 '23 at 18:46
  • Does this answer your question? [Can I reuse code for selecting a custom DTO object for a child property with EF Core?](https://stackoverflow.com/questions/66378438/can-i-reuse-code-for-selecting-a-custom-dto-object-for-a-child-property-with-ef) – Svyatoslav Danyliv Apr 15 '23 at 04:29
  • Consider using Automapper for this with it's `ProjectTo` method. Considering your naming convention is consistent between your Entities and DTOs, you would just need to declare a confirguration for each entity and it's respective DTO (no explicit properties to map) then instead of `.Select(x => new ContentReadDTO { .... })` you use `.ProjectTo(config)` where "config" is the mapping configuration. Automapper handles all of the related entity mapping so long as it knows what to convert them to. It can save having to reinvent the wheel. – Steve Py Apr 15 '23 at 05:04

0 Answers0