Search code examples
c#entity-frameworklinq

Cannot implicitly convert type 'System.Collections.Generic.List<<anonymous type: decimal SSN, string FullName>>' to 'System.Collections.Generic.List<>


I got this error when I tried to make a method to return all users which have no users

CS0029 Cannot implicitly convert type 'System.Collections.Generic.List<<anonymous type: decimal SSN, string FullName>>' to 'System.Collections.Generic.List'

I have two classes first class

public partial class User
{
    public int Id { get; set; }

    public string? FullName { get; set; }

    public string? UserName { get; set; }

    public string? Password { get; set; }

    public string? Role { get; set; }

    public decimal? EmpId { get; set; }

    public DateTime? CreatedDate { get; set; }

    public DateTime? EditedDate { get; set; }

    public virtual Employee? Emp { get; set; }

}

second class

public partial class Employee
{
    public decimal Ssn { get; set; }

    public int? EmpCode { get; set; }

    public string? EmpFirstName { get; set; }

    public string? EmpSecondName { get; set; }

    public string? EmpLastName { get; set; }

    public virtual User? User { get; set; }

}

and I want to create a method to return all users which have no users

I wrote this code in EmployeesEF class

public List<string> GetAllEmpsIsNotUser()
{
    try
    {

        var query = from emp in db.Employees
               join user in db.Users on emp.Ssn equals user.EmpId into userGroup
               from u in userGroup.DefaultIfEmpty()
               where !db.Users.Any(u => u.EmpId == emp.Ssn)
               select new
               {
                   SSN = emp.Ssn,
                   FullName = emp.EmpFirstName + " " + emp.EmpSecondName + " " + emp.EmpLastName
               };

        return query.ToList();
    }
    catch
    {
        return new List<string>();

    }
}

Solution

  • The compilation error is clear. You are returning the value of List<anonymous> type but your method expects to return the value of List<string> type.

    Would recommend creating a DTO (Data Transfer Object) class instance.

    public class UserModel
    {
        public string Ssn { get; set; }
        public string FullName { get; set; }
    }
    

    Your method should return the value of List<UserModel> type.

    Also, since you are performing the LEFT JOIN query and want to obtain the record that doesn't have the User record. You can achieve it with u == null without needing the subquery to find the record from the User table (!db.Users.Any(u => u.EmpId == emp.Ssn)).

    public List<UserModel> GetAllEmpsIsNotUser()
    {
        try
        {
    
            var query = from emp in db.Employees
                   join user in db.Users on emp.Ssn equals user.EmpId into userGroup
                   from u in userGroup.DefaultIfEmpty()
                   where u == null
                   select new UserModel
                   {
                       SSN = emp.Ssn,
                       FullName = emp.EmpFirstName + " " + emp.EmpSecondName + " " + emp.EmpLastName
                   };
    
            return query.ToList();
        }
        catch
        {
            return new List<UserModel>();
        }
    }