创建泛型函数以过滤具有相同基类的许多对象

时间:2018-02-19 15:56:21

标签: c# entity-framework linq inheritance

我正在尝试创建一个通用函数来传递我打算用于项目中许多对象的过滤器。所有这些对象都有一个名为BaseObject的基类。

例如:

public class Artist : BaseObject
{
    public string Name { get; set; }
    //...more properties
}

public class Album : BaseObject
{
    public string Title { get; set; }
    //...more properties
}

BaseObject具有以下内容:

public class BaseObject
{
    public BaseObject()
    {
        Oid = Guid.NewGuid();
    }

    [Key]
    public Guid Oid { get; set; }

    [ScaffoldColumn(false)]
    public DateTime? DateCreated { get; set; }

    [ScaffoldColumn(false)]
    public DateTime? DateUpdated { get; set; }

    [ScaffoldColumn(false)]
    public DateTime? DateDeleted { get; set; }

    [ScaffoldColumn(false)]
    public bool IsDeleted { get; set; }

}

我想创建一个可以用于艺术家和专辑的方法,我有以下内容,但是没有用,我不理解<T>

public static IQueryable<Entities.Core.BaseObject> WhereActive<T>(this IQueryable<Entities.Core.BaseObject> query)
{
    return query.Where<Entities.Core.BaseObject>(b => !b.IsDeleted);
}

上面,我尝试将Entities.Core.BaseObject替换为T,但无效。

当我使用Where子句调用db.Artist时:

Artist artist = db.Artist
            .WhereActive<Artist>()
            .Where(a => string.IsNullOrEmpty(a.Name.Trim()))
            .FirstOrDefault();

我收到错误:

  

'BaseObject'不包含'Name'的定义,并且没有扩展方法'Name'接受类型'BaseObject'的第一个参数(你是否缺少using指令或汇编引用?)

我确信这是一个简单的解决方法,但我是LINQ的新手。

2 个答案:

答案 0 :(得分:4)

您需要返回IQueryable<T>,并在T上设置通用约束,以指定它是Entities.Core.BaseObject(或从中派生的类)

public static IQueryable<T> WhereActive<T>(this IQueryable<T> query) 
    where T : Entities.Core.BaseObject
{
    // no need to specify the generic <T> here as well...
    return query.Where(b => !b.IsDeleted);
}

答案 1 :(得分:3)

您需要将通用参数约束为从BaseObject继承,并将其用作扩展方法的输入和输出。

    public static IQueryable<T> WhereActive<T>(this IQueryable<T> query)
        where T: BaseObject
    {
        return query.Where(b => !b.IsDeleted);
    }