简体   繁体   中英

Search in all childrens that inherit from a parent using EF / Linq

I have this situation: For example, I have this classes:

1)

public abstract class User
{
    public int Id { get; set; }
    public string Name { get; set; }
}

2)

public class Administrator: User
{
    public string SpecificAdministratorAttribute { get; set;}
}

3)

public class OtrherClass: User
{
    public string SpecificOtherClassAttribute { get; set; }
}

4)

public class OtherKindOfAdministrator: User
{
    public string SpecificAdministratorAttribute { get; set; }
}

As you can see the attribute "SpecificAdministratorAttribute" is being repeated in two classes.

Now, i need make a linq query to search for all Users that meet this condition:

  • Name = "zzz"
  • SpecificAdministratorAttribute = "xxx"

How can I search for all USERS (Parent) that meet this conditions. One of the solutions is to move this attribute to the parent class and leave it null in some cases. What could be the best solution to this scenario?

And how if I have an attribute that is only present in one of the child classes but I need to search it from USERS (Parent), without Knowing from what of the children's class is? Suppose that you need to get all the USERS that meets SpecificOtherClassAttribute = "uuu" ? There is any way to search this from USERS not from OTHERCLASS (Children) ? (I need an example using Linq)

public class Admin: User
{
    public string AdminAttribute { get; set; }
}

public class AdministratorTypeA: Admin
{

}

public class AdministratorTypeB: Admin
{

}

Query like this:

users.Where(u=> u is Admin && u.Name= "zzz" && (u as Admin).AdminAttribute=="xxx");

There are several approaches to solve this problem.

One is, as Walter mentioned, to create a base class for Admin and inherit from it. Then you can check if user is an admin and if yes get an appropriate attribute.

The other one is to add an interface so you won't have to change any of your classes (just add inheritance from the interface to each of them):

public interface IAdministrator 
{
    string SpecificAdministratorAttribute { get; set;}
}

public class OtherKindOfAdministrator: User, IAdministrator

And then you can search with LINQ checking if your object is IAdministrator.

These two approaches have the same problem: execution time. The problem is that database can't make things like is Administrator or is IAdministrator . So you will retrieve all users and then will be individually casting them to needed type to see if they are corresponding to it or not.

The solution for this would be to add a property to the User class called UserType (or IsAdmin bool property if you have only admins and not admins here) so you can easily determine who is an administrator and who is not. So then you will be able to retreive only administrators from the database and then extract these you need:

users.Where(u => u.UserType == UserTypes.Admin).Select(u => u as Administrator).Where(u => u.Name == ”zzz” && u.AdminAttribute == ”xxx”);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM