1

我有以下代码:

public class CrudModel<T> : ICrudModel<T> where T : DomainBase
{
    public IQueryable<T> GetAll()
    {
        return Repository.Query<T>();
    }
}

问题是一些对象(T)我需要做一个额外的过滤器,所以我创建了一个单独的方法,如下所示:

public IEnumerable<TR> GetAllwithinOrg<TR>() where TR : DomainBase, IFilterable
{
    var items = Repository.Query<TR>();
    return FilterwithinOrg(items);
}

其中过滤器方法如下所示:

public IEnumerable<TResult> FilterwithinOrg<TResult>(IEnumerable<TResult> linked) where TResult :  IFilterable
{
    var dict = GetDict();
    return linked.Where(r => dict.ContainsKey(r.Id));
}

这一切都很好,但问题是我必须记住调用方法 1 或方法 2(基于对象是否支持IFilterable接口

在这个问题上,我得到了这样做的建议:

public IQueryable<T> GetAll()
{
    var items = Repository.Query<T>();
    if (typeof(IFilterable).IsAssignableFrom(typeof(T)))
    {
        items = FilterwithinOrg(items.Cast<IFilterable>()).Cast<T>().AsQueryable();
    }
    return items;
}

所以我可以用一种方法支持这两种用例。这似乎可行,但我试图了解这样做会带来什么样的性能影响

items.Cast<IFilterable>()).Cast<T>().AsQueryable()

如果它很糟糕,那么我将记住从外部调用 2 个单独的方法,但显然只有一个会很方便。有什么建议么?

如果我忘记调用第二种方法,但我想再次查看是否可以将其保留为仅一种方法,以使其对外部调用者更简单,我想我会将其保留为备份。

4

3 回答 3

1

在 CrudModel 类中使用另一种带有 where 子句的方法怎么样?

public IEnumerable<T> GetAll<T>(Func<T, bool> whereClause) where T : DomainBase
{
    var items = Repository.Query<T>();
    return items.Where(whereClause);
}

并调用使用

List<int> intList = new List<int>() { 1 };
intList.GetAll<int>((i) => sampledict.ContainsKey(i));

我觉得通过将逻辑限制在一个 GetAll 方法中来使事情变得复杂是不合适的,而且由于 CrudModel 似乎是通用的,最好有一个接受任何条件的通用方法。

于 2013-04-28T05:29:28.013 回答
0

首先,我觉得你有一个GetAll函数有点奇怪,但是对于某些类型,你开始过滤,导致没有得到所有:)

除此之外,我不认为你有很大的性能损失......本质上你会在你内部做一个额外的检查GetAll- 方法:typeof(IFilterable).IsAssignableFrom(typeof(T))就像一个普通的演员。你几乎不会感觉到。

也许过滤器本身可以改进。你创建一个字典。字典是否每次调用都具有相同的值,还是会发生变化。如果您只使用键而不使用值,为什么还要使用字典?一个HashSet<T>呢?

于 2013-04-28T07:59:11.430 回答
0

与数据库查询所花费的时间相比,铸造时间可以忽略不计。但是,您正在根据此处的代码查询整个表并在内存中过滤:

public IEnumerable<TResult> FilterwithinOrg<TResult>(IEnumerable<TResult> linked) where TResult :  IFilterable
{
    var dict = GetDict();
    return linked.Where(r => dict.ContainsKey(r.Id));
}

请记住,您需要过滤查询,而不是列表,因此您应该将方法更改为接受并返回IQueryable<TResult>,例如:

public IQueryable<TResult> FilterwithinOrg<TResult>(IQueryable<TResult> linked) where TResult :  IFilterable
{
    var dictKeys = GetDict().Keys.ToList();
    return linked.Where(r => dictKeys.Contains(r.Id));
}

请注意,过滤器表达式必须具有等效的 SQL 表达式,否则会发生运行时错误。

于 2013-04-28T12:28:27.200 回答