当前位置:  开发笔记 > 编程语言 > 正文

是否可以将IEnumerable用作私有类级变量?

如何解决《是否可以将IEnumerable用作私有类级变量?》经验,为你挑选了1个好方法。

我有一个MVC 5网站,它使用Entity Framework进行数据库交互.

我想在控制器中使用IEnumerable作为私有变量,以便同一控制器中的其他自定义ActionResults可以使用相同的信息,而无需每次都重新查询.我不是指其他CRUD ActionResults,而是指其他自定义方法,这些方法使用在Index页面上看到的数据执行操作,该页面通常是完整数据库表的子集.查询一次然后重新使用相同的数据会很有帮助.

在这个例子中,我有private IEnumerable _data;一个类级变量和IEnumerable data一个Index()级变量.我Debug.WriteLine用来确定每个变量是否为空.

正如我所料,在Index()ActionResult的范围内,变量data_data都不为null.内ClickedFromIndexPageLink()的范围内,_data -类级别变量为空.

我的理论是,虽然我首先按顺序加载了索引,但控制器并不知道.就控制器而言,当我在另一个ActionResult中请求_data内容时,它还没有被填充.然而,在现实的时候,我已经按下指数第一,所以应该会看到_data充满指数查询.

要查看我的解决方法,请向下滚动以查看"方法B(确实有效,但重复)".

有没有简单的方法让IEnumerable以这种方式用作私有类变量,或者我的解决方法是唯一可行的方法?

方法A(不起作用):

Debug.WriteLine()结果:

Begin Index() test *****
Is data Null? Not Null
Is _data Null? Not Null
End Index test *****

Begin ClickedFromIndexPageLink() test*****
Is _data Null? Null
End ClickedFromIndexPageLink test*****

代码:

using IenumerableAsClassVariable.Models;
using System.Collections.Generic;
using System.Data.Entity;
using System.Diagnostics;
using System.Linq;
using System.Net;
using System.Web.Mvc;

namespace IenumerableAsClassVariable.Controllers
{
    // This is the helper class & function used to determine if the IEnumerable is null or empty
    public static class CustomHelpers
    {
        public static string IsNullOrEmpty(this IEnumerable enumerable)
        {
            if (enumerable == null)
                return "Null";
            else
                return "Not Null";
        }
    }

    public class CourseListsController : Controller
    {
        private CreditSlipLogContext db = new CreditSlipLogContext();
        private IEnumerable _data;

        // If IEnumerable is null or empty return true; else false.       

        // GET: CourseLists
        public ActionResult Index()
        {
            IEnumerable data = db.CourseLists.AsEnumerable();
            Debug.WriteLine("-----");
            Debug.WriteLine("Begin Index test *****");
            Debug.WriteLine("Is data Null? " + CustomHelpers.IsNullOrEmpty(data));
            _data = data;
            Debug.WriteLine("Is _data Null? " + CustomHelpers.IsNullOrEmpty(_data));
            Debug.WriteLine("End Index test *****");           

            return View(db.CourseLists.ToList());
        }

        public ActionResult ClickedFromIndexPageLink()
        {

            Debug.WriteLine("Begin ClickedFromIndexPageLink test*****");
            Debug.WriteLine("Is _data Null? " + CustomHelpers.IsNullOrEmpty(_data));
            Debug.WriteLine("End ClickedFromIndexPageLink test*****");

            ViewBag.IsDataNull = CustomHelpers.IsNullOrEmpty(_data);

            return View();
        }

        #region OtherCrudActionResultsAreHidden
        #endregion

    }
}

方法B(确实有效,但重复):

正如我所料,我的结果不是空的:

Begin ClickedFromIndexPageLink test*****
Is data Null? Not Null
Is _data Null? Not Null
End ClickedFromIndexPageLink test*****

这是因为我在ActionResult中重新查询,就像我在Index()ACtionResult中一样:

public ActionResult ClickedFromIndexPageLink()
        {
            IEnumerable data = db.CourseLists.AsEnumerable();

            Debug.WriteLine("Begin ClickedFromIndexPageLink test*****");
            Debug.WriteLine("Is data Null? " + CustomHelpers.IsNullOrEmpty(data));
            _data = data;
            Debug.WriteLine("Is _data Null? " + CustomHelpers.IsNullOrEmpty(_data));
            Debug.WriteLine("End ClickedFromIndexPageLink test*****");

            ViewBag.IsDataNull = CustomHelpers.IsNullOrEmpty(_data);

            return View();
        }

Shyju.. 5

每次调用action方法都是一个单独的Http请求.请记住,Http是无状态的,并且一个请求不知道先前的请求是做什么的.因此,您将无法获得在上一个操作方法调用中设置的私有变量值.

您可以考虑缓存多个请求可用的数据,直到缓存过期.您可以使用MemoryCachedot net中提供的类.

快速样品

const string  CacheKey = "courses";
public ActionResult Index()
{
    var courseList = GetCourses();
    // do something with courseList 
    return View(courseList );
}
public ActionResult List()
{
    var course = GetCourses();
   // do something with courseList 
    return View(course);
}

private List GetCourses()
{
    var db = new YourDbContext();
    var cache = MemoryCache.Default;
    if (!cache.Contains(CacheKey))  // checks to see it exists in cache
    {
        var policy = new CacheItemPolicy();
        policy.AbsoluteExpiration = DateTime.Now.AddDays(1);

        var courses = db.CourseLists.ToList();
        cache.Set(CacheKey , courses, policy);
    }
    return (List) cache.Get(CacheKey);
}

当然,您可以将其从控制器代码移到新的类/层,以保持关注点分离.

如果您希望在存储到缓存之前将实体对象转换为简单的POCO/ViewModel集合,

 var courseVms = db.CourseLists.Select(s=>new CourseViewModel {
                          Id =s.Id, Name=s.Name }).ToList();

 cache.Set(cacheKey, courseVms , policy);

而你的GetCourses方法将返回一个 List

请记住,缓存将保留数据,直到缓存过期.因此,保留通常不会经常更改的数据是一个好主意(例如:查找数据等).如果要缓存事务数据,则每次对数据进行更改时都需要更新缓存(例如:添加新课程,删除一门课程等).

MemoryCacheclass驻留在驻留的System.Runtime.Caching名称空间中System.Runtime.Caching.dll.因此,您需要添加对此程序集的引用.

如果要在ASP.NET5/MVC6应用程序中执行相同类型的缓存,可以IMemoryCache按照本答案中的说明使用实现.



1> Shyju..:

每次调用action方法都是一个单独的Http请求.请记住,Http是无状态的,并且一个请求不知道先前的请求是做什么的.因此,您将无法获得在上一个操作方法调用中设置的私有变量值.

您可以考虑缓存多个请求可用的数据,直到缓存过期.您可以使用MemoryCachedot net中提供的类.

快速样品

const string  CacheKey = "courses";
public ActionResult Index()
{
    var courseList = GetCourses();
    // do something with courseList 
    return View(courseList );
}
public ActionResult List()
{
    var course = GetCourses();
   // do something with courseList 
    return View(course);
}

private List GetCourses()
{
    var db = new YourDbContext();
    var cache = MemoryCache.Default;
    if (!cache.Contains(CacheKey))  // checks to see it exists in cache
    {
        var policy = new CacheItemPolicy();
        policy.AbsoluteExpiration = DateTime.Now.AddDays(1);

        var courses = db.CourseLists.ToList();
        cache.Set(CacheKey , courses, policy);
    }
    return (List) cache.Get(CacheKey);
}

当然,您可以将其从控制器代码移到新的类/层,以保持关注点分离.

如果您希望在存储到缓存之前将实体对象转换为简单的POCO/ViewModel集合,

 var courseVms = db.CourseLists.Select(s=>new CourseViewModel {
                          Id =s.Id, Name=s.Name }).ToList();

 cache.Set(cacheKey, courseVms , policy);

而你的GetCourses方法将返回一个 List

请记住,缓存将保留数据,直到缓存过期.因此,保留通常不会经常更改的数据是一个好主意(例如:查找数据等).如果要缓存事务数据,则每次对数据进行更改时都需要更新缓存(例如:添加新课程,删除一门课程等).

MemoryCacheclass驻留在驻留的System.Runtime.Caching名称空间中System.Runtime.Caching.dll.因此,您需要添加对此程序集的引用.

如果要在ASP.NET5/MVC6应用程序中执行相同类型的缓存,可以IMemoryCache按照本答案中的说明使用实现.

推荐阅读
coco2冰冰
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有