Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/asp.net-mvc/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/entity-framework/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Asp.net mvc 在MVC应用程序中使用静态EF对象上下文是否有助于提高性能?_Asp.net Mvc_Entity Framework - Fatal编程技术网

Asp.net mvc 在MVC应用程序中使用静态EF对象上下文是否有助于提高性能?

Asp.net mvc 在MVC应用程序中使用静态EF对象上下文是否有助于提高性能?,asp.net-mvc,entity-framework,Asp.net Mvc,Entity Framework,让我们从这个基本场景开始: 我有一堆基本上很少更改的枚举表(例如地理位置、类别等),我想将它们加载到我的EF ObjectContext中,以便将它们分配给引用它们为FK的实体。这些对象还用于填充各种下拉控件。到目前为止,这是相当标准的场景 由于在MVC中为每个页面请求创建了一个新的控制器,因此会创建一个新的实体上下文,并重复加载这些“enum”对象。我考虑在控制器(或存储库对象)的所有实例中使用静态上下文对象 但这是否需要太多的锁定,从而实际恶化性能 或者,我正在考虑只对只读表使用静态上下文。

让我们从这个基本场景开始:

我有一堆基本上很少更改的枚举表(例如地理位置、类别等),我想将它们加载到我的EF ObjectContext中,以便将它们分配给引用它们为FK的实体。这些对象还用于填充各种下拉控件。到目前为止,这是相当标准的场景

由于在MVC中为每个页面请求创建了一个新的控制器,因此会创建一个新的实体上下文,并重复加载这些“enum”对象。我考虑在控制器(或存储库对象)的所有实例中使用静态上下文对象

但这是否需要太多的锁定,从而实际恶化性能

或者,我正在考虑只对只读表使用静态上下文。但是,由于引用它们的实体无论如何都必须在相同的上下文中,这与上面的内容没有任何区别

我也不想参与附加/分离这些枚举对象的工作。因为我相信一旦我将一个静态枚举对象附加到一个实体,我就不能再将它附加到另一个实体


请帮忙,我对EF+MVC还很陌生,所以我想知道最好的方法是什么。

我已经使用Linq2SQL实现了类似的功能,在应用程序启动时检索这些“查找表”作为列表,并将它们存储在ASP的缓存机制中。通过使用ASP缓存,我不必担心线程/锁定等问题。不确定为什么需要将它们附加到上下文,如果需要,可以通过表PK id轻松检索类似的内容。

个人而言,我调用数据库(CRUD)时,从来没有任何静态上下文内容等我将该上下文用于单个事务/工作单元

因此,在本例中,您的建议是希望从数据库中检索一些数据。。这个数据是。。或多或少只读,不更改/静态

查找数据就是一个很好的例子

所以你的分类永远不会改变。你的地理位置也永远不会改变

我不会在数据库/持久性级别担心这个概念,而是在应用程序级别。因此,请忘记此数据是静态/只读的。。就这样吧。然后,当您在应用程序中(即ASP.NET web MVC控制器方法或global.asax代码)时,您应该缓存此。。。在UI层上

如果你正在做一个很好的n层MVC应用程序,它包含

  • 用户界面层
  • 服务/业务逻辑层
  • 持久性/数据库数据层
<>我会把这个缓存在中间层。由UI层调用(即MVC控制器操作..例如public void Index())

我认为知道如何区分你的顾虑是很重要的。。数据库的内容应该是->CRUD'ish的内容和一些独特的存储过程。不必担心缓存数据等问题。请尽可能使该层保持轻巧和简单


然后,您的中间层(如果存在)或顶层应该担心如何处理此数据->在这种情况下,缓存它,因为它是非常静态的。

我认为这是一个缓存什么和如何缓存的问题。当您处理EF时,当您尝试跨不同上下文持久化EF对象并尝试分离/附加这些对象时,可能会很快遇到问题。如果您将自己的POCO对象与自定义t4模板一起使用,那么这不是问题,但是如果您使用的是vanilla EF,那么您将希望为缓存创建POCO对象

对于大多数简单的查找项(即数字主键和字符串文本描述),可以使用字典。如果有多个字段需要通过UI传递和返回,那么可以构建更完整的对象模型。因为这些将是POCO对象,所以它们可以以您喜欢的任何方式保存在几乎任何地方。我建议在MVC应用程序之外使用缓存逻辑,以便可以轻松模拟缓存活动进行测试。如果需要缓存多个列表,可以将它们全部放在一个容器类中,该容器类如下所示:

public class MyCacheContainer
{
    public Dictionary<int, string> GeoLocations { get; set; }

    public List<Category> Categories { get; set; }
}
MyEntityObject item = Context.MyEntityObjects.FirstOrDefault(i => i.Id == id);
MyCacheContainer cache = CacheFactory.GetCache();
MyViewModel model = new MyViewModel { Item = item, GeoLocationDescription = GeoLocations[item.GeoLocationId] };
myItem.Category = Context.Categories.FirstOrDefault(c => c.id == id);
如果绝对必须在上下文中包含这些对象(即,如果存在将2个或多个其他表连接在一起的引用实体),则可以将该缓存容器传递到数据访问层,以便它能够进行适当的查找

至于分配“有效”实体,在.NET4中,您只需设置外键属性,而不必实际附加对象(从技术上讲,您可以在3.5中这样做,但设置键需要魔法字符串)。如果您使用的是3.5,您可以尝试以下内容:

public class MyCacheContainer
{
    public Dictionary<int, string> GeoLocations { get; set; }

    public List<Category> Categories { get; set; }
}
MyEntityObject item = Context.MyEntityObjects.FirstOrDefault(i => i.Id == id);
MyCacheContainer cache = CacheFactory.GetCache();
MyViewModel model = new MyViewModel { Item = item, GeoLocationDescription = GeoLocations[item.GeoLocationId] };
myItem.Category = Context.Categories.FirstOrDefault(c => c.id == id);
虽然这不是最优雅的解决方案,并且确实需要到DB的额外往返才能获得您真正不需要的类别,但它是有效的。基于主键执行单记录查找实际上不应该有那么大的影响,特别是如果表很小,如您所说的查找数据类型


如果你被3.5卡住了,不想做额外的往返,你想走魔幻字符串的路线,只要确保你为你的魔幻字符串使用某种类型的静态资源和/或代码生成器,这样你就不会对它们指手画脚了。这里有很多例子说明了如何在不去数据库的情况下为引用分配一个新的EntityKey,所以我不会在这个问题上讨论这个问题。

非常有趣的问题,可能会让我今晚很晚才醒来调查这是否可以做到。谢谢回答,Pure.Krome。如果我可以在其他EF上下文调用中使用缓存的Categories EntitySet作为引用,那么这是一个很好的解决方案。但我不能。如果EF的工作方式类似于Linq2SQL(或者EF4.0与FK关联),那么我可以简单地使用PK ID,故事到此结束。但不幸的是,我现在不能这么做。我必须为cre的父实体分配有效类别