0

我正在为 Add、Remove 和 Find 实现泛型,因为我正在实现多租户,它允许我从数据库访问 IQueryables,而不是 DbSets。

Add 是如何实现的:

之前的代码:

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”必须是引用类型才能在泛型类型或方法“App.Context.TenantContext.Find(T)”Service.cs 中用作参数“T”

我对泛型有点陌生,这里的任何帮助将不胜感激。

4

1 回答 1

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);

上面的示例返回 a SingleOrDefault,但您也可以轻松地返回集合(预过滤IQueryablesIEnumerables) using .Wherebools using.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将保持整个实体图(实体及其导航/集合属性)与上下文分离,这可能比使用.Find. 如果您以后想在突变代码中使用相同的实体实例,您可以在那时将其附加到上下文中。

于 2013-11-04T18:17:42.047 回答