在MVC控制器中加载和重用List <datarow>对象的最佳方法是什么

时间:2016-04-06 11:23:03

标签: c# asp.net-mvc-4 razor

我正在开发一个MVC项目虽然我是MVC的新手,我有一个正在加载数据库值的函数。我在同一控制器内的不同位置使用此功能。当我检查了SQL分析器时,我发现每次运行我使用该功能的程序。

我的问题是什么是使用函数的最佳方法,该函数将在第一次调用该过程,从下次开始,它将使用相同的值。

提前致谢

更新:

public List<DataRow> SalesCount()
{          
    List<DataRow> lstSales = new List<DataRow>();
    string str_salesClass = adding session value here;    
    return lstSales = SalesRepository.SalesCount(SessionValue);        
}

2 个答案:

答案 0 :(得分:1)

Controller中有几种方法可以做到这一点。首先,您应该知道,对于控制器的每个请求,您都在使用同一控制器的不同的实例。

第一种方式:使用单身人士。将值存储在公共静态实例中,加载一次并在每次询问时获取相同的List。但是,由于它是数据库值 - 您需要定期更新数据库中的存储值。

public class LoaderSingleton
{
    private static readonly LoaderSingleton _instance = new LoaderSingleton();
    private List<DataRow> _items;
    static LoaderSingleton()
    {

    }

    private LoaderSingleton()
    {

    }

    public static LoaderSingleton Instance
    {
        get
        {
            return _instance;
        }
    }

    public List<DataRow> Items
    {
        get
        {
            if (this._items == null)
            {
                this.Load();
            }

            return this._items;
        }
    }

    public void Load()
    {
        this._items = //perform load from database
    }
}

第二种方式:使用Session变量。将值存储在用户会话中而不是静态类中。你不应该忘记更新值和清理会话。

//inside controller
this.Session[str_salesClass] = SalesRepository.SalesCount();

第三种方式:使用ViewData变量。值将仅存储在请求之间,您应该在最后一个请求完成后使用新值更新它。

//inside controller
this.ViewData[str_salesClass] = SalesRepository.SalesCount();

第四种方式:从您的视图中执行async次请求。例如,您要将所需的值加载到基本视图,这可以异步加载另一个视图,当您发送加载子视图的请求时 - 您应该将加载的数据作为参数传递。

public ActionResult BaseView()
{
    ViewBag.Data = SalesRepository.SalesCount();
    return View();
}

[ChildActionOnly]
public ActionResult ChildView1(List<DataRow> sales)
{

}

我不建议使用Cache,因为它有不可预测的行为。当你没有被期待时,你会得到null

答案 1 :(得分:0)

您可以使用MemoryCache来保存SQL查询结果,并且仅在某些参数更改或缓存值需要无效时才有新请求。

对于配置缓存参数,您可以使用CacheItemPolicy类。您可以配置指示在指定的持续时间后是否应该逐出缓存条目的值,通过触发器使缓存状态无效的额外监视器以及其他参数。

// your controller field
private readonly MemoryCache _dbDataCache = MemoryCache.Default;

// string key for your cached data
private const string DbDataCacheSalesCountKey = "DbDataCacheSalesCountKey";

public List<DataRow> SalesCount()
{
    if(_dbDataCache.Contans(DbDataCacheSalesCountKey))
        return _dbDataCache[DbDataCacheSalesCountKey] as List<DataRow>;

    string str_salesClass = adding session value here;  
    var lstSales = SalesRepository.SalesCount(SessionValue);

    // save cache only for 10 minutes
    var cip = new CacheItemPolicy { AbsoluteExpiration = new DateTimeOffset(DateTime.Now.AddMinutes(10)) };
    _dbDataCache.Set(DbDataCacheSalesCountKey, lstSales, cip);
    return lstSales;
}

替代代码组织看起来像下一个,并且使用以下代码:

public List<DataRow> SalesCount()
{
    var salesCount = _dbDataCache[DbDataCacheSalesCountKey] as List<DataRow>;
    if(salesCount == null)
    {
        string str_salesClass = adding session value here;  
        salesCount = SalesRepository.SalesCount(SessionValue);

        // save cache only for 10 minutes
        var cip = new CacheItemPolicy { AbsoluteExpiration = new DateTimeOffset(DateTime.Now.AddMinutes(10)) };
        _dbDataCache.Set(DbDataCacheSalesCountKey, salesCount, cip);
    }

    return salesCount;
}