Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/322.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
C# 用实体框架实现ASP.NETMVC5中的并发_C#_Asp.net_Asp.net Mvc_Entity Framework_Asp.net Mvc 5 - Fatal编程技术网

C# 用实体框架实现ASP.NETMVC5中的并发

C# 用实体框架实现ASP.NETMVC5中的并发,c#,asp.net,asp.net-mvc,entity-framework,asp.net-mvc-5,C#,Asp.net,Asp.net Mvc,Entity Framework,Asp.net Mvc 5,我正在使用实体框架在ASP.NETMVC5中开发简单的CMS。 我对MVC应用程序中的并发性有几个问题 首先-未经任何身份验证的用户的“我的应用”部分的“公共”部分: 所有数据帖子、类别信息、标签和文档都使用实体存储在数据库中 在控制器的公共部分,只有读或写数据到数据库,而不是删除或编辑 所以我的第一个问题——是否有必要在公共部分中使用一些机制来避免并发危险?当多个用户同时浏览我的网站时,一切都正常吗 然后需要我的管理部门身份验证: 可以有多个用户扮演多个角色,但实际上只有少数注册用户 用户可以

我正在使用实体框架在ASP.NETMVC5中开发简单的CMS。 我对MVC应用程序中的并发性有几个问题

首先-未经任何身份验证的用户的“我的应用”部分的“公共”部分:

所有数据帖子、类别信息、标签和文档都使用实体存储在数据库中

在控制器的公共部分,只有读或写数据到数据库,而不是删除或编辑

所以我的第一个问题——是否有必要在公共部分中使用一些机制来避免并发危险?当多个用户同时浏览我的网站时,一切都正常吗

然后需要我的管理部门身份验证:

可以有多个用户扮演多个角色,但实际上只有少数注册用户 用户可以在数据库中创建/编辑/删除数据 我知道一些安全机制对于安全系统是必要的,但是你能帮我怎么做吗

我还在每个方法中使用DbContext的这种模式,其中DB是必要的:

using (var db = new CmsContext()) { // other stuff here }
使用var db=new CmsContext { //这里还有其他东西 }

而不是在所有方法中使用的一个类变量db。是这样吗


谢谢你的回答

关于用户仅检索/写入数据的第一个问题,并发性不会成为问题。他们永远不会尝试同时更新/删除一行。管理部分是另一个故事。您希望多个管理员用户将同时使用数据库,这将导致出现以下情况:admin1获取记录并对其进行编辑,但当它重新插入该记录时,该记录已由admin2更新。有两种方法可以处理此问题:

悲观并发:这意味着您正在对数据库的某些记录使用锁。当一个进程正在更新某个记录时,这些行被锁定,其他进程无法同时对其进行编辑。不幸的是,实体框架不支持这一点。 乐观并发:EF支持这一点,这意味着您的数据库中有一个额外的列,其版本为rowversion。当进程尝试重新插入记录时,它将首先检查行版本是否没有更改。如果相同,则插入记录。如果已更改,则会重新蚀刻记录,并再次编辑值。关于乐观并发的Msdn文档。 在代码模型中,您可以使用[TimeStamp]属性定义一个额外属性:

[TimeStamp]
public virtual byte[] RowVersion {get; set;}
或者在fluent API中,您可以这样映射它:

modelBuilder<MyEntity>().HasProperty(p => p.RowVersion).IsRowVersion();
您也可以将整行用作“rowversion”来检查更改,但通常会使用额外的列。否则,如果只想更新1个字段,则必须将整行发送到数据库,因为需要检查行版本。还请注意,[TimeStamp]仅适用于字节数组,如果要使用其他类型,则必须使用[ConcurrencyCheck]属性。如果将整行用作行版本,则必须将此属性应用于所有属性

是否需要一些机制来避免并发危险 在公共区?当多个用户同时使用时,一切都是正确的吗 同时在浏览我的网站吗

据我所见,并发性与两个人同时编辑同一条记录有关。考虑到公共部分没有任何编写方法,避免并发机制是不必要的,也是不可能的

我知道一些安全机制是建立安全系统的必要条件, 但是你能帮我怎么做吗

您可以在其他类中编写查询,如存储库和/或服务。在谷歌搜索存储库和服务实体框架时,我发现了这个链接,听起来很有趣

我还在每个方法中使用DbContext的这种模式,其中DB是 必要的:

using (var db = new CmsContext()) { // other stuff here }
而不是在所有方法中使用的一个类变量db。这是吗 对吧?

这是一个很难回答的问题。现在很难说什么是对的还是错的。有很多人,有几种不同的观点。在我看来,你的例子不是最好的方法,但并不意味着它是错误的。当使用存储库类时,我们通常只有一个DbContext实例。看看这条线


希望这有帮助

首先,您应该了解并发可能导致异常的所有情况。一些常见的案例,通常是关于关系和合同的

写入和更新:

表包含一些唯一的约束,因此您可以检查实体是否存在,如果不存在,则尝试创建一个实体。现在两个并发操作执行检查,都得到空结果,并且都尝试创建实体。一个操作将因异常而失败,而另一个操作更幸运,并首先创建了实体

表包含外键:通过创建新实体,其他一些操作删除了依赖项entr Y结果是——例外

任何标量值的并发更新都不会导致任何异常,但最后一个会赢

<> P>所以你必须考虑你的APP/DB和场景的结构,并决定你想做些什么来防止不同步的并发更新/写入。 你能反对什么

锁 这里的问题可能是您有多个实例,因为它只是服务器级锁

交易 数据库锁

using (var ctx = new DbCtx) {
    ctx.Database.Connection.Open();
    using (var transaction = ctx.Database.BeginTransaction(IsolationLevel.Serializable))
    {
        try {
            // check + update
            transaction.Commit();
        }
        catch (Exception) {
            transaction.Rollback();
        }
    }
    ctx.Database.Connection.Close();
}

谷歌的第一个链接给了我这个,它有很好的开始内容@AlexanderDerck已经提取了对您有用的内容。