在你急于思考之前?null合并运算符:
string result = myParent.objProperty.strProperty ?? "default string value if strObjProperty is null";
Run Code Online (Sandbox Code Playgroud)
这里的问题是当myParent或objProperty为null时,它会在达到strProperty的评估之前抛出异常.
要避免以下额外的空检查:
if (myParent != null)
{
if (objProperty!= null)
{
string result = myParent.objProperty.strProperty ?? "default string value if strObjProperty is null";
}
}
Run Code Online (Sandbox Code Playgroud)
我通常使用这样的东西:
string result = ((myParent ?? new ParentClass())
.objProperty ?? new ObjPropertyClass())
.strProperty ?? "default string value if strObjProperty is null";
Run Code Online (Sandbox Code Playgroud)
因此,如果对象为null,则它只创建一个新对象才能访问该属性.
哪个不是很干净.
我想要一个像'???'的东西 运营商:
string result = (myParent.objProperty.strProperty) ??? "default string value if strObjProperty is null";
Run Code Online (Sandbox Code Playgroud)
...它将从括号内的任何"null"中存活,以返回默认值.
谢谢你的提示.
摘要
这个问题是关于方法论的。答案应该是在针对所描述的场景的上下文中与圣杯的链接。
我们在MVC Web应用程序项目中遇到了与dbContext的使用相关的不同问题。
在阅读了许多问答博客,文章……(包括具有存储库和注入模式的提案,Owin,Entity Framework,Ninject)之后,我们仍然不清楚使用dbContext的正确方法。
在MVVC表示层/域实体/逻辑/数据访问层之间进行分隔(包括身份安全处理用户和角色权限)时,是否有任何文章,演示以及与“ CRUD”操作相比更复杂的应用程序中使用“方法”的方法?
描述
以前,我们的方法是在每个存储库中需要时创建dbContext对象。很快,由于连接与存储库功能一起消失,我们发现了诸如“ dbContext已处置”之类的错误。这使得检索到的对象“部分可用”到应用程序的上层(使用技巧.ToList(),这是有限的,因为我们可以访问集合和属性,但以后不能导航到对象子表,依此类推)。同样使用来自不同存储库的2个上下文,我们得到了一个异常,告诉我们2个上下文正在尝试将更改注册到同一对象。
由于要及时交付原型,因此我们为整个应用程序创建了一个静态dbContext共享,可以在需要时从任何地方调用它(控制器,模型,逻辑,DataAccess,数据库初始化器)。我们知道这是一个非常肮脏的解决方法,但是比以前的方法效果更好。
仍然存在问题:dbContext一次只能处理1个异步方法调用,并且我们可以有很多调用(例如,userManager.FindByNameAsync-只有异步方法)。例外:“在先前的异步操作完成之前,第二个操作在此上下文上启动”。
我们正在考虑将上下文创建为在控制器中调用动作的第一步,然后将该对象作为“中继竞赛”传递给所调用的所有其他层或函数。这样,连接将从“单击浏览器”开始,直到将响应重新加载到该连接上为止。但是我们不喜欢每个函数都必须有一个额外的参数“上下文”的想法,只是为了共享整个操作路径中各层的连接。
我们确信我们不是第一个想知道使用上下文的正确方法的人。
应用层
我们有这些(逻辑)层,不同的工作空间,但从上到下都是相同的webapp MVC项目:
视图: HTML + Razor + JQuery + CSS。此处的代码仅限于布局,但是某些HTML可能取决于Role。方法调用仅针对控制器,加上utils(如格式设置)。
ViewModels:在控制器和视图之间交换的数据容器。类仅定义属性,以及仅与域实体(译者)之间进行转换的函数。
控制器:从浏览器调用的操作导致对逻辑层中功能的调用。此处的身份验证限制了对操作的访问或操作内部的限制。控制器避免使用Domain实体,而避免使用ViewModels,以便与逻辑层进行通信,从而调用ViewModels转换函数。
域实体:用于逻辑层,并用于由实体框架创建数据库表。
逻辑类:域实体具有包含所有操作的EntityLogic类。这些是所有特定客户客户端通用和抽象的规则(ViewModel未知)的核心。
存储库:用于访问数据库。不确定我们是否确实需要这样做,因为Entity Framework已经将Domain实体映射到数据库中的对象。
典型场景
浏览器在产品控制器中调用操作(POST)以编辑产品。ProductViewModel用作数据的容器。
控制器操作仅限于角色集合。在动作内部,根据角色,将调用另一个Logic函数,并将ProductViewModel转换为ProductDomainEntity并作为参数传递。
逻辑EditProduct函数调用不同逻辑类中的其他函数,并且还使用本地化和安全性进行限制或过滤。逻辑可以调用或不调用存储库来访问数据,或为所有对象使用全局上下文,并将生成的域实体集合传递给逻辑。
根据结果,逻辑可能会或可能不会尝试浏览结果的子级集合。结果作为域实体(或的集合)返回给控制器操作,并且根据此结果,控制器可以调用更多Logic,或者重定向到另一个操作,或者使用将结果转换为正确ViewModel的View进行响应。
在哪里,何时何地以及如何创建dbContext以最佳方式支持整个操作?

更新:逻辑层中的所有类都是静态的。像这样从控制器调用方法:
UserLogic.GetCompanyUserRoles(user)
Run Code Online (Sandbox Code Playgroud)
, 要么
user.GetCompanyRoles()
Run Code Online (Sandbox Code Playgroud)
其中GetCompanyRoles()是在UserLogic中实现的User的扩展方法。因此,没有Logic类的实例意味着没有构造函数接收dbContext以便在其方法中使用。
我想让静态类中的静态方法知道在哪里将dbContext的实例激活到当前HttpRequest。
莫非NInject和OnePerRequestHttpModule帮助,这?有人尝试过吗?