- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
最终答案:
我在 InRequestScope() 方法中使用了@WiktorZychla answer 和 Ninject 的组合。我重构了我的存储库以接受上下文注入(inject),然后在我的 NinjectControllerFactory 中添加了以下行:
ninjectKernel.Bind<EFDbContext>().ToSelf().InRequestScope();
(注意:我替换了:
ninjectKernel.Bind<ISellingLocation>().To<EFSellingLocationRepository>().InRequestScope().WithConstructorArgument("context",new EFDbContext());
我在其中一条评论中提到的行,其中:
ninjectKernel.Bind<ISellingLocation>().To<EFSellingLocationRepository>();
因为它导致了错误)
我还使用 nuget 安装了 Ninject.MVC3,它创建了文件:“NinjectWebCommon.cs”,其中包含以下行:
DynamicModuleUtility.RegisterModule(typeof(OnePerRequestHttpModule));
虽然有人说这一行是可选的,但其他文章指出应该使用它以使 InRequestScope 在 MVC 站点中正常工作。
原问题:
我目前有几个 EF 存储库,每个都类似于以下内容:
public class EFCityRepository : ICityRepository
{
private EFDbContext context = new EFDbContext();
public bool Create(City cityToCreate)
{
...
}
public City Get(int cityID)
{
...
}
}
如您所见,现在我对所有操作都使用单一的全局 EFDbContext,从我读到的内容来看这是不好的 - 所以我尝试将它(在 Create、Get 和其他方法中)更改为“using”语句,类似于以下内容:
public City Get(int cityID)
{
using(EFDbContext context)
{
...some opeartions…
return entities;
}
}
现在我遇到了很多与实体延迟加载相关的问题,我不得不使用类似下面的方法:
context.Entry(getResult.FirstOrDefault()).Reference(x => x.Address).Load();
context.Entry(getResult.FirstOrDefault()).Reference(x => x.Agency).Load();
context.Entry(getResult.FirstOrDefault().Address).Reference(x => x.City).Load();
只是为了简单起见以我想要的方式工作,否则每次我尝试访问 Address 时,我都会得到:“ObjectContext 实例已被处理,不能再用于需要连接的操作” .当然,当上下文是全局的时,它工作正常。
我需要一些建议:我应该使用本地上下文并使用预加载而不是延迟加载吗?还是这里可以接受全局背景?
还有一个人到底是怎么想使用延迟加载的呢?正如我所见 - 我必须为使用某些存储库的每个操作编写单独的逻辑 - 或者我错了吗?
编辑 1:
@Askolein:
好的,目前我的应用程序包含几个子项目:
Common
Domain - here I have my repositories
Helpers
Utils
WebUI
我用来触发错误的存储库如下所示:
public interface ISellingLocation
{
KeyValuePair<bool, Exception> Create(SellingLocation sellingLocationToAdd);
KeyValuePair<SellingLocation, Exception> Get(int sellingLocationID);
KeyValuePair<bool, Exception> Update(SellingLocation sellingLocationToUpdate);
KeyValuePair<bool, Exception> Delete(int sellingLocationID);
KeyValuePair<List<SellingLocation>, Exception> GetAll();
KeyValuePair<List<SellingLocation>, Exception> GetAll(int agencyID);
KeyValuePair<List<SellingLocation>, Exception> GetFiltered(string filter);
KeyValuePair<List<SellingLocation>, Exception> GetFiltered(Expression<Func<SellingLocation, bool>> filter);
KeyValuePair<bool, Exception> DisableSellingLocations(List<int> sellingLocationsIDs);
}
以及 GetFiltered 方法的实现,如下所示:
public KeyValuePair<List<SellingLocation>, Exception> GetFiltered(Expression<Func<SellingLocation, bool>> filter)
{
Exception lastException = null;
using (var transaction = new TransactionScope())
{
using (EFDbContext context = new EFDbContext())
{
try
{
var getResult = context.SellingPoints.Where(filter).ToList();
//var getResult2 = getResult.ToList();
context.Entry(getResult.FirstOrDefault()).Reference(x => x.Address).Load();
context.Entry(getResult.FirstOrDefault()).Reference(x => x.Agency).Load();
context.Entry(getResult.FirstOrDefault().Address).Reference(x => x.City).Load();
transaction.Complete();
return new KeyValuePair<List<SellingLocation>, Exception>(getResult, lastException);
}
catch (Exception ex)
{
lastException = ex;
return new KeyValuePair<List<SellingLocation>, Exception>(new List<SellingLocation>(), ex);
}
}
}
}
我在我的 Controller 中调用这个方法是这样的:
var allSellingLocationsForCurrentUser = sellingLocationRepository.GetFiltered(x => x.IsEnabled);
if(allSellingLocationsForCurrentUser.Value == null)
{
AgencySalesSellingLocationsListViewModel agencySalesSellingLocationsListViewModel = new AgencySalesSellingLocationsListViewModel();
foreach (var item in allSellingLocationsForCurrentUser.Key)
{
agencySalesSellingLocationsListViewModel.aaData.Add(new AgencySalesSellingLocationsListViewModelRow()
{
ID = item.SellingLocationID,
DT_RowId = item.SellingLocationID.ToString(),
Name = item.Name,
City = item.Address.City.Name,
Street = item.Address.Street
});
}
return Json(agencySalesSellingLocationsListViewModel, JsonRequestBehavior.AllowGet);
}
我明白为什么我会收到错误,正如我之前所说 - 如果我明确告诉实体加载:Address、Agency 和 Address.City - 它会工作得很好。
@WiktorZychla:
我当前的 DataContext 如下所示:
public class EFDbContext : DbContext
{
public EFDbContext():base("DefaultConnection")
{
}
public DbSet<User> Users { get; set; }
public DbSet<UserData> UserDatas { get; set; }
public DbSet<Address> Addresses { get; set; }
public DbSet<SkillCategory> SkillCategories {get;set;}
public DbSet<Skill> Skills {get;set;}
public DbSet<SkillAnswer> SkillAnswers { get; set; }
//public DbSet<UserSkills> UserSkills { get; set; }
public DbSet<User2Skill> User2Skill { get; set; }
public DbSet<Agency> Agencies { get; set; }
public DbSet<UniversalDictionary> UniversalDictionaries { get; set; }
public DbSet<UserAddressTimeTable> UserAddressTimeTables { get; set; }
public DbSet<City> Cities { get; set; }
public DbSet<SellingLocation> SellingPoints { get; set; }
}
如果我理解正确 - 我将不得不封装我的 EFCityRepository 并使用类似的东西:
using(SomeContext context = new SomeContext())
{
EFCityRepository repository = new EFCityRepository(context);
var result = repository.Get(id);
...do some work...
}
是不是有点过分了?现在我使用 Ninject,并使用存储库接口(interface)(IUserRepository、IUserRepository 等)注入(inject)我的 Controller - 所以我的 Controller 方法像工作单元一样工作,如果我理解正确 - 我将不得不:将我的 DbContext 注入(inject)我的 Controller 方法,或者在 Controller 方法和存储库之间创建另一个层...我理解正确吗?
@宠儿:
正如我上面所说的——我将我的 Controller 方法视为工作单元……如果我要实现你建议的东西——我应该把它放在哪里?内部域或 WebUI?它必须是存储库和 Controller 之间的另一层,对吗?
谢谢大家的建议。
最好的问候
最佳答案
与其将上下文本地化到存储库方法中,不如换一种方式——使存储库独立于上下文:
public class EFCityRepository : ICityRepository
{
public EFCityRepository( EFDbContext context )
{
this.context = context;
}
private EFDbContext context;
public bool Create(City cityToCreate)
{
...
}
public City Get(int cityID)
{
...
}
}
这种方法为您提供了最大的灵 active 。您可以在存储库之间共享完全相同的上下文,每个存储库都可以有一个额外的上下文,无论如何。
对于基于 Web 的应用程序,通常的做法是让您的上下文“按请求”共享,这意味着在单个请求中使用完全相同的上下文,并且在请求管道的末尾处理它。
编辑:正如 Maess 所建议的,您绝对应该考虑通过依赖注入(inject)引擎(如 Unity 或 Ninject)半自动管理上下文生命周期的可能性。 DI 引擎还可以通过自动解析构造函数依赖性来显着帮助您。这是另一回事,但可能是您的架构向前迈出的坚实一步。
关于c# - Entity Framework - 全局 vs 局部上下文 vs 延迟加载,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21408746/
我想要显示正在加载的 .gif,直到所有内容都已加载,包括嵌入的 iframe。但是,目前加载 gif 会在除 iframe 之外的所有内容都已加载后消失。我怎样才能让它等到 iframe 也加载完毕
首先,这是我第一次接触 Angular。 我想要实现的是,我有一个通知列表,我必须以某种方式限制 limitTo,因此元素被限制为三个,在我单击按钮后,其余的应该加载。 我不明白该怎么做: 设置“ V
我正在尝试在我的设备上运行这个非常简单的应用程序(使用 map API V2),并且出于某种原因尝试使用 MapView 时: 使用 java 文件: public class MainMap e
我正在使用 Python 2.6、Excel 2007 Professional 和最新版本的 PyXLL。在 PyXLL 中加载具有 import scipy 抛出异常,模块未加载。有没有人能够在
我想做这个: 创建并打包原始游戏。然后我想根据原始游戏中的蓝图创建具有新网格/声音/动画和蓝图的其他 PAK 文件。原始游戏不应该知道有关其他网格/动画/等的任何信息。因此,我需要在原始游戏中使用 A
**摘要:**在java项目中经常会使用到配置文件,这里就介绍几种加载配置文件的方法。 本文分享自华为云社区《【Java】读取/加载 properties配置文件的几种方法》,作者:Copy工程师。
在 Groovy 脚本中是否可以执行条件导入语句? if (test){ import this.package.class } else { import that.package.
我正在使用 NVidia 视觉分析器(来自 CUDA 5.0 beta 版本的基于 eclipse 的版本)和 Fermi 板,我不了解其中两个性能指标: 全局加载/存储效率表示实际内存事务数与请求事
有没有办法在通过 routeProvider 加载特定 View 时清除 Angular JS 存储的历史记录? ? 我正在使用 Angular 创建一个公共(public)安装,并且历史会积累很多,
使用 Xcode 4.2,在我的应用程序中, View 加载由 segue 事件触发。 在 View Controller 中首先调用什么方法? -(void) viewWillAppear:(BOO
我在某些Django模型中使用JSONField,并希望将此数据从Oracle迁移到Postgres。 到目前为止,当使用Django的dumpdata和loaddata命令时,我仍然没有运气来保持J
创建 Nib 时,我需要创建两种类型:WindowNib 或 ViewNib。我看到的区别是,窗口 Nib 有一个窗口和一个 View 。 如何将 View Nib 加载到另一个窗口中?我是否必须创建
我想将多个env.variables转换为静态结构。 我可以手动进行: Env { is_development: env::var("IS_DEVELOPMENT")
正如我从一个测试用例中看到的:https://godbolt.org/z/K477q1 生成的程序集加载/存储原子松弛与普通变量相同:ldr 和 str 那么,宽松的原子变量和普通变量之间有什么区别吗
我有一个重定向到外部网站的按钮/链接,但是外部网站需要一些时间来加载。所以我想添加一个加载屏幕,以便外部页面在显示之前完全加载。我无法控制外部网站,并且外部网站具有同源策略,因此我无法在 iFrame
我正在尝试为我的应用程序开发一个Dockerfile,该文件在初始化后加载大量环境变量。不知何故,当我稍后执行以下命令时,这些变量是不可用的: docker exec -it container_na
很难说出这里问的是什么。这个问题是含糊的、模糊的、不完整的、过于宽泛的或修辞性的,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开它,visit the help center 。 已关
我刚刚遇到一个问题,我有一个带有一些不同选项的选择标签。 现在我想检查用户选择了哪些选项。 然后我想将一个新的 html 文件加载到该网站(取决于用户选中的选项)宽度 javascript,我该怎么做
我知道两种保存/加载应用程序设置的方法: 使用PersistentStore 使用文件系统(存储,因为 SDCard 是可选的) 我想知道您使用应用程序设置的做法是什么? 使用 PersistentS
我开始使用 Vulkan 时偶然发现了我的第一个问题。尝试创建调试报告回调时(验证层和调试扩展在我的英特尔 hd vulkan 驱动程序上可用,至少它是这么说的),它没有告诉我 vkCreateDeb
我是一名优秀的程序员,十分优秀!