type 'T' must be a reference type in order to use it as parameter 'TEntity' in the generic type or method

0

When I try to query using IQueryable , I receive the following error:

  

Error 3 The type 'T' should be a reference type in order to use it as   parameter 'TEntity' in the generic type or method   'System.Data.Entity.DbContext.Set ()'

1st - I have 3 entities

Parent class that is an interface: does not have a table in it for it

public interface IParentEquipment
{
    string DaughterOperativeNumber { get; }
}

and two child classes that are abstract:

[Table("TB_EQPT_SUB")]
public abstract class EquipmentSub : IParentEquipment
{
    [Column("OPERATIVE_NUMBER")]
    public string OperativeNumber { get; set; }

    public string DaughterOperativeNumber
    {
        get { return this.OperativeNumber ; }
    }
}

[Table("TB_EQPT")]
public abstract class Equipment : IParentEquipment
{
    [Column("OPERATIVE_NUMBER")]
    public string OperativeNumber { get; set; }

    public string DaughterOperativeNumber
    {
        get { return this.OperativeNumber ; }
    }
}

I have a method to fetch a EquipmentSub or Equipment via the operative number.

  public T FindGenericEquipmentByOperativeNumber<T>(string operativeNumber) where T : IParentEquipment
    {
        IQueryable<T> query = _ctx.Set<T>();
        QueryFilter<T> queryFilter = new QueryFilter<T>();
        query = query.Where(s => !(s.DaughterOperativeNumber.Equals(operativeNumber)));
        query = query.Where(queryFilter.GetFilter);
        return query.Single();
    }

I noticed that if I change my IParentEquipment interface, for an abstract error some.

public abstract class IParentEquipment{

}

Why can not I use an interface in my query?

    
asked by anonymous 12.07.2018 / 21:50

2 answers

1

The error happens because the constraint method of Set asks that type T (the type that the method expects) is a type for reference ( where TEntity : class ). > Putting an interface in constraint does not force the type to be by reference, so the error.

To fix, add the constraint new() or class .

where T : class, IParentEquipment

where T : new(), IParentEquipment

You can read about the restrictions at: Constraints on type parameters (C # Programming Guide)

    
12.07.2018 / 21:52
2

Because the signature of the method you are using requires this:

public virtual Microsoft.EntityFrameworkCore.DbSet<TEntity> Set<TEntity> () where TEntity : class;

Documentation .

For some reason I can investigate it needs the adjacent type to be a class, so it has set class to constraint, so an interface can not be used directly. You can indirectly, in the type you will use there.

So you have to use a similar constraint, you can use a class or a new() , it will require a concrete type, even if it is characterized by the interface.

    
12.07.2018 / 21:54