实体框架泛型从特定类继承的实体的位置

时间:2017-11-16 15:31:23

标签: c# entity-framework repository-pattern

这里我有一个从教程页面复制的通用Repository类,但具体来说我的问题在于最后两个函数。在我的项目中,我有几个继承自CRUDProperties类的目录实体,并且在所有这些实体中都有一个属性“Activo”,我当前想要做的是,如果实体继承自CRUDProperties类,我将获得所有具有Activo属性的实体是的,如果它们不从该类继承,它只会获取所有实体。但是编译器会抛出一个错误,说明已经定义了T.我该怎么办?

public class Repository<T> where T : class
{
    private readonly projectEntities context;
    private IDbSet<T> entities;
    string errorMessage = string.Empty;

    public Repository(projectEntities context)
    {
        this.context = context;
    }

    public T GetById(object id)
    {
        return context.Set<T>().Find(id);
    }

    // This is the function that throws me a compilation error
    public virtual IList<T> GetAll<T>() where T : CRUDProperties
    {
        return context.Set<T>().Where(c => c.Activo).ToList();
    }

    public virtual IList<T> GetAll()
    {
        return context.Set<T>().ToList();
    }
}

2 个答案:

答案 0 :(得分:1)

编译器抱怨类型参数的模糊命名。该类已经有一个名为<?php require __DIR__ . '/../vendor/autoload.php'; // If account is public you can query Instagram without auth $instagram = new \InstagramScraper\Instagram(); $medias = $instagram->getMedias('kevin', 25); // Let's look at $media $media = $medias[0]; echo "Media info:\n"; echo "Id: {$media->getId()}\n"; echo "Shotrcode: {$media->getShortCode()}\n"; echo "Created at: {$media->getCreatedTime()}\n"; echo "Caption: {$media->getCaption()}\n"; echo "Number of comments: {$media->getCommentsCount()}"; echo "Number of likes: {$media->getLikesCount()}"; echo "Get link: {$media->getLink()}"; echo "High resolution image: {$media->getImageHighResolutionUrl()}"; echo "Media type (video or image): {$media->getType()}"; $account = $media->getOwner(); echo "Account info:\n"; echo "Id: {$account->getId()}\n"; echo "Username: {$account->getUsername()}\n"; echo "Full name: {$account->getFullName()}\n"; echo "Profile pic url: {$account->getProfilePicUrl()}\n"; // If account private you should be subscribed and after auth it will be available $instagram = \InstagramScraper\Instagram::withCredentials('username', 'password', 'path/to/cache/folder'); $instagram->login(); $medias = $instagram->getMedias('private_account', 100); 的类型参数,因此在类的上下文中,类型参数名已经被&#34;采取&#34;。

但是,您应该能够通过将方法的类型参数重命名为T以外的其他内容来完成您想要的操作,因此您更改的方法可能如下所示:

T

注意:我假设public virtual IList<TCrud> GetAll<TCrud>() where TCrud : CRUDProperties { return context.Set<TCrud>().Where(c => c.Activo).ToList(); } 是一个类...如果它是一个接口,那么你还需要将CRUDProperties约束复制到该方法(即将其更改为class

答案 1 :(得分:0)

使用此方法,您可以将custom where子句传递给GetAll方法

public virtual IList<T> GetAll<T>(Expression<Func<T, bool>> predicate)
{
    return context.Set<T>().Where(predicate).ToList();
}

在这个方法中我们首先检查T类型是否具有Activo属性,如果找到此属性,我们创建一个自定义表达式树并替换为返回所有记录的默认谓词,此函数仅返回在activo属性中具有true值的记录

public virtual IList<T> GetAll<T>()
{
    Expression<Func<T, bool>> predicate = t => true;
    if(typeof(T).GetProperty("Activo") != null)
    {

        var epx = Expression.Parameter(typeof(T), "x");
        Expression left =  Expression.PropertyOrField(epx, "Activo");
        Expression right = Expression.Constant(true);
        Expression e1 = Expression.Equal(left, right);

        predicate = Expression.Lambda<Func<T, bool>>(e1, new ParameterExpression[] { epx });
    }
    return context.Set<T>().Where(predicate);
}