Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using generics with entities

In PersonBusiness.GetQuery method, the PersonEntity is peppered all over code and there are a lot of other entity types that will implement this method similarly.

I want to use generic parameters in PersonBusiness to lessen usage of specific entity type because there will be implementations like this one with other entities and i want to prevent some other type used instead of the intended entity type. But could not be successful or satisfied by generic parameter used versions.

I also want to use interfaces instead of concrete classes if it is more meaningful.

public class Entities: DbContext
{
    public virtual DbSet<PersonEntity> PersonSet { get; set; }
}
public class PersonEntity
{
    public int Id { get; set; }
    public string FullName { get; set; }
}
public class BaseBusiness
{
    public Entities Db => new Entities();
}

public abstract class BaseBusiness<T> : BaseBusiness where T : class
{
    public IQueryable<T> GetQuery<TKey>(Expression<Func<T, bool>> where,
        Expression<Func<T, TKey>> orderBy)
    {
        IQueryable<T> query = Db.Set<T>();
        if (where != null)
            query = query.Where(where);
        if (orderBy != null)
            query = query.OrderBy(orderBy);

        return query;
    }

    public abstract IQueryable<T> ApplyDefaultOrderyBy(IQueryable<T> query);

    public IQueryable<T> GetQuery(IQueryable<T> query, string orderBy, Func<IQueryable<T>, IQueryable<T>> defaultOrderBy = null)
    {
        if (orderBy != null)
            query = query.OrderBy(orderBy);
        else
            query = defaultOrderBy != null ? defaultOrderBy(query) : ApplyDefaultOrderyBy(query);

        return query;
    }
}

public class PersonBusiness : BaseBusiness<PersonEntity>
{
    public IQueryable<PersonEntity> GetQuery(string orderBy, int? groupId)
    {
        IQueryable<PersonEntity> query = Db.PersonSet;

        Func<IQueryable<PersonEntity>, IQueryable<PersonEntity>> defaultOrderBy = null;
        if (groupId.HasValue)
        {
            query = query.Where(d => d.Id == groupId);
        }
        else
        {
            defaultOrderBy = q => q.OrderBy(d => d.Id).ThenBy(d => d.FullName);
        }
        return GetQuery(query, orderBy, defaultOrderBy);
    }
    public override IQueryable<PersonEntity> ApplyDefaultOrderyBy(IQueryable<PersonEntity> query)
    {
        return query.OrderBy(q => q.FullName);
    }
}
like image 333
lockedscope Avatar asked May 03 '17 14:05

lockedscope


People also ask

What is generic entity?

Generic entity identifier means a number or other identifier assigned to a category of vendors and not specific to any individual or entity.

How do I create a generic entity?

Create an instance directly by supplying the generic type information with the entity. For example the following code shows how to create a response containing the result of a method invoked via reflection: Method method = ...; GenericEntity<Object> entity = new GenericEntity<Object>( method. invoke(...), method.

What is generic in Overview?

Generics means parameterized types. The idea is to allow type (Integer, String, … etc., and user-defined types) to be a parameter to methods, classes, and interfaces. Using Generics, it is possible to create classes that work with different data types.

What is a. net generic?

NET: A generic type definition is a class, structure, or interface declaration that functions as a template, with placeholders for the types that it can contain or use. For example, the System. Collections.


1 Answers

Despite my comment on the post, I figured I'd put an answer up here which compiles. As I don't understand the use case, it's hard to reason about a proper solution. Never-the-less here is the code

public class PersonBusiness<T> : BaseBusiness<T> where T: PersonEntity
{
    public IQueryable<T> GetQuery(string orderBy, int? groupId)
    {
        IQueryable<T> query = Db.Set<T>();

        Func<IQueryable<T>, IQueryable<T>> defaultOrderBy = null;
        if (groupId.HasValue)
        {
            query = query.Where(d => d.Id == groupId);
        }
        else
        {
            defaultOrderBy = q => q.OrderBy(d => d.Id).ThenBy(d => d.FullName);
        }
        return GetQuery(query, orderBy, defaultOrderBy);
    }
    public override IQueryable<T> ApplyDefaultOrderyBy(IQueryable<T> query)
    {
        return query.OrderBy(q => q.FullName);
    }
}

Updated to use DbSet in favor of Cast, per the comment from @Ivan Stoev.

like image 61
Jeffrey Patterson Avatar answered Oct 07 '22 12:10

Jeffrey Patterson