实现通用查找<t>方法</t>

时间:2013-11-04 18:11:07

标签: c# asp.net entity-framework generics dbcontext

我正在为添加,删除和查找实现泛型,因为我正在实现多租户,这使我可以从数据库访问IQueryables,而不是DbSets。

如何实施添加:

之前的代码:

interest = db.Interests.Add(new Interest()) // Interests is dbSet

之后的代码:

interest = db.Add(new Interest()) // Interests is dbSet

// in db class
public T Add<T>(T item) where T : class, ITenantData
    {
        var set = _appContext.Set<T>();
            return set.Add(item);
    }

这很有效。现在我正在尝试为Find做同样的事情,但因为我正在使用Id而不是Typed参数,所以我有点卡住了。

之前的代码:

var aptitude = db.Aptitudes.Find(interest.AptitudeId);  // Aptitudes is a DbSet

之后的代码:

var aptitude = db.Find(interest.AptitudeId); // how to identify type?

我不能这样做:

var aptitude = db.Aptitudes.Find(interest.AptitudeId);

因为Aptitudes现在是一个IQueryable。

所以这目前失败了:

public T Find<T>(T query) where T : class, ITenantData
    {
        var set = _mentorContext.Set<T>();
        return set.Find(query);
    }

因为没有识别出类型 - 我得到:

  

类型'int'必须是引用类型才能将其用作   泛型类型或方法中的参数'T'   'App.Context.TenantContext.Find(T)'Service.cs

我对仿制药有点新意,这里的任何帮助都会非常感激。

1 个答案:

答案 0 :(得分:1)

使用扩展方法解决此问题。

public IQueryable<T> Query<T>() where T : class, ITenantData
{
    return _mentorContext.Set<T>().AsNoTracking();
}

......同时在另一堂课......

public static MentorContextExtensions
{
    public static InterestEntity ByAptitudeId(
        this IQueryable<InterestEntity> queryable, 
        int aptitudeId)
    {
        return queryable.SingleOrDefault(x => x.AptitudeId == aptitudeId);
    }
}

...针对IQueryable<T> ...

的使用情况
db.Query<InterestEntity>().ByAptitudeId(interest.AptitudeId);

上面的示例返回SingleOrDefault,但您可以使用IQueryablesIEnumerables轻松返回集合(预先过滤的.Wherebool)使用.Any

要在.Find上保持IDbSet(按主键)方法的使用,您可以这样做:

public T Find<T>(params object[] keyComponents) where T : class, ITenantData
{
    return _mentorContext.Set<T>().Find(keyComponents);
}

...并像这样使用它......

var aptitude = db.Find<Aptitude>(interest.AptitudeId);

...也就是说,使用.Find在使用某种突变代码进行插入,更新,删除实体时可能会更快。 .Find将始终将实体附加到上下文,这是您需要变更数据时所需的内容。但是,您无法在其上调用.AsNoTracking(),因为它返回单个实体。如果您只需要实体读取其属性或用于显示目的,.AsNoTracking将使整个实体图(实体及其导航/集合属性)与上下文分离,这可能比使用{{1更快}}。如果您以后想要在变异代码中使用相同的实体实例,那么您可以在那时将它附加到上下文。