使用C#中的泛型掌握数据缓存

时间:2019-03-21 05:53:05

标签: c# generics

我正在尝试使用静态变量缓存我所有经常使用且很少更新的数据,以便在很大程度上减少数据库查询。以下是我的代码。

public class Cache
{
    private static ApplicationDbContext _context;

    private static IEnumerable<ActivityGroupDto> _ActivityGroups;

    public static IEnumerable<ActivityGroupDto> ActivityGroups(bool ForceRefresh = false)
    {
        if (ForceRefresh || _ActivityGroups == null)
        {
            _context = new ApplicationDbContext();
            _ActivityGroups = Mapper.Map<IEnumerable<ActivityGroup>, IEnumerable<ActivityGroupDto>>(_context.ActivityGroups.ToList());
        }

        return _ActivityGroups;
    }
}

我的项目中有很多这样的列表,并且我不想对所有列表重复该方法(应用DRY原理)。想到使用泛型而感到震惊,却没有真正想到如何将上述方法转换为泛型。以下是我的代码。

public class Master<T,T1,T2,T3>
{
    private static ApplicationDbContext _context;
    public static IEnumerable<T> Process(T Data, bool ForceRefresh = false)
    {
        if (ForceRefresh || Data == null)
        {
            _context = new ApplicationDbContext();
            Data = Mapper.Map<IEnumerable<T1>, IEnumerable<T2>>(_context.Set<T3>());
        }

        return Data;
    }
}

请提出建议。

1 个答案:

答案 0 :(得分:0)

我认为您将类型混为一谈,在这种情况下,您应该需要大约2种类型,即将数据转换为DTO,ActivityGroup => ActivityGroupDto

我已经概述了一个类似的类,它使用List而不是IEnumerable,但是应该在正确的方向上为您提供帮助。

public class MasterCache<T, TDto>
{
    private static ApplicationDbContext _context;

    private static List<TDto> _dtoGroups;

    public static List<TDto> Process(T data, bool ForceRefresh = false)
    {
        if (ForceRefresh || _dtoGroups == null)
        {
            _context = new ApplicationDbContext();
            _dtoGroups = Mapper<T, TDto>.Map(data);
        }

        return _dtoGroups;
    }
}

要真正受益,您的映射器也需要通用,这是一个简单的框架:

public class Mapper<T, TDto>
{
    public static List<TDto> Map(T groups)
    {
        return new List<TDto>();
    }
}

在顶部,您可以创建通用的应用程序上下文。

请记住static变量在泛型类中的行为方式(即,每个封闭的泛型实例的副本创建一次)。

  

根据评论进行了更新。

要存储和检索不同的实体,我们可以使用类型为键的字典和对象为值的

Dictionary<Type, object> test = new Dictionary<Type, object>();
test.Add(typeof(ActivityGroup), new object());
var result = test[typeof(ActivityGroup)];

这将涉及将值转换为正确的类型,一种变通办法是使所有静态列表实现标准包装器接口(这取决于您的设计和列表的用途),并使用此方法存储价值观。由于我相信您是从该系统开始的,并且我不知道它的大小,因此我不认为转换性能现在应该成为问题。为了进行验证,您始终可以在转换后检查对象是否为必需类型。