1

I have a conversion error in my program. I use a method to query db (with Entity Framework) and get all the entries of a table Web_Groups_joint_Profils:

public partial class Web_Group_joint_Profils
{
    [Key]
    [Column(Order = 0)]
    [StringLength(255)]
    public string GroupName { get; set; }

    [Key]
    [Column(Order = 1)]
    [DatabaseGenerated(DatabaseGeneratedOption.None)]
    public int IDProfil { get; set; }
}

And here is the method to get all rows:

public List<Web_Group_joint_Profils> GetGroupAndId()
{
    var grpId = context.WebGroupProfil
               .Select(a => new 
               {
                   GroupName = a.GroupName,
                   IDProfil = a.IDProfil
               }).ToList();
    return grpId;
 }

But grpId is invalid :

Impossible to implicitely convert type "System.Collections.Generic.List<> to System.Collections.Generic.List"

When I hover on the declaration ToList() it says

Creates a List<T> of an IEnumerable<out T>

So I have tried changing the return type

List<IEnumerable<T>> 

without success. I'm guessing my linq query creates an anonymous type I don't know how to handle.

Salah Akbari
  • 39,330
  • 10
  • 79
  • 109
Flexabust Bergson
  • 732
  • 14
  • 34

3 Answers3

1

The type of the method is List<Web_Group_joint_Profils> but you are returning a List of anonymous type. You can change it like this:

.Select(a => new Web_Group_joint_Profils
{
    GroupName = a.GroupName,
    IDProfil = a.IDProfil
}).ToList();

And if you still get error probably it is because you cannot project onto a mapped entity then you need to create a DTO class with needed properties from the Web_Group_joint_Profils entity like this:

public class TestDTO
{
    public string GroupName { get; set; }
    public string IDProfil { get; set; }
}

Then:

.Select(a => new TestDTO
{
    GroupName = a.GroupName,
    IDProfil = a.IDProfil
}).ToList();
Salah Akbari
  • 39,330
  • 10
  • 79
  • 109
  • Actually this throws a NotSupportedException, that is why I changed to anonymous type – Flexabust Bergson Jun 29 '17 at 08:58
  • @LéonardLaiter it is because you cannot project onto a mapped entity then you need to create a DTO class with needed properties. Check my updated answer. – Salah Akbari Jun 29 '17 at 09:05
  • @S.Akbari Ok thanks, Colin's answer is more practical for my needs, or I would be creating DTOs all over the place, it's not what I want right now, but I'll keep this in mind thanks! – Flexabust Bergson Jun 29 '17 at 09:06
1

The .Select() creates an object of an anonymous type, so the list will necessarily be the same anonymous type. This is not the same type as you are returning.

What you need the .Select() to do is create an object of the type you desire. However, Entity Framework won't like that because it will try and convert that to SQL which it can't.

So, your code probably needs to be something like this:

public List<Web_Group_joint_Profils> GetGroupAndId()
{
    var grpId = context.WebGroupProfil
        .Select(a => new 
        {
            GroupName = a.GroupName,
            IDProfil = a.IDProfil
        })
        .AsEnumerable() // This forces EF to run the query and materialise the data as anon objects
        .Select(a=>new Web_Group_joint_Profils(a.GroupName, a.IDProfil)
        .ToList();
    return grpId;
}

I've assumed that Web_Group_joint_Profils has a constructor that takes the two arguments. If not just modify the construction to fit your scenario.

Colin Mackay
  • 18,736
  • 7
  • 61
  • 88
  • is `.AsEnumerable()` a better choice than `.ToList()` for materializing? I've always used `.ToList()` before (maybe it doesn't matter?) – default Jun 29 '17 at 09:12
  • 1
    @Default I think `AsEnumerable()` is indeed a better operation because it uses simple operations whereas `ToList()` method has O(n) complexity as suggested in this post : https://stackoverflow.com/questions/15516462/is-there-a-performance-impact-when-calling-tolist – Flexabust Bergson Jun 29 '17 at 09:40
  • Although, that thread doesn't say that AsEnumerable has any other complexity. What do you mean by using simple operations? – default Jun 29 '17 at 10:03
0

Instead of creating a list of anonymous objects, in your LINQ select object initialiser create your required object:

.Select(a => new Web_Group_joint_Profils
{
Chris Pickford
  • 8,642
  • 5
  • 42
  • 73