我使用实体框架为项目创建了一个原型,现在它可以正常工作了,我想使程序可以投入生产。

我在EF方面面临许多挑战,其中最大的挑战是并发管理(这是一种财务软件)。

鉴于似乎无法用EF处理悲观并发,我不得不切换到SQL中的存储过程。

老实说,我有点担心可能带来的工作量。

我想知道以前是否有人遇到过相同情况,以及使用EF将.net代码转换为原始SQL的最佳策略是什么?

编辑:我正在研究CLR,但尚不清楚是否可以使用它来管理悲观的并发性。 在这种情况下,它是否比TSQl更有趣? 如果我理解得很清楚,它将使我可以重用部分C#代码和调用另一个函数的函数结构。

===============>>#1 票数:1 已采纳

我在那里,好消息是,如果您不想的话,您不必放弃Entity Framework。 坏消息是您必须自己更新数据库。 这并不像看起来那么难。 我目前正在使用EF 5,但计划使用EF6。我不明白为什么这对于EF 6仍然不起作用。

第一件事是在DbContext的构造函数中将其强制转换为IObjectContextAdapter并获得对ObjectContext的访问权。 我为此做一个财产

public virtual ObjectContext ObjContext
{
    get
    {
        return ((IObjectContextAdapter)this).ObjectContext;
    }
}

一旦您订阅了SavingChanges事件-这不是我们的确切代码,则某些内容将从其他方法中复制出来并重做。 这只是让您了解需要做什么。

ObjContext.SavingChanges += SaveData;

private void SaveData(object sender, EventArgs e)
{
    var context = sender as ObjectContext;
    if (context != null)
    {
        context.DetectChanges();
        var tsql = new StringBuilder();
        var dbParams = new List<KeyValuePair<string, object>>();

        var deletedEntites = context.ObjectStateManager.GetObjectStateEntries(EntityState.Deleted);
        foreach (var delete in deletedEntites)
        {
            // Set state to unchanged - so entity framework will ignore
            delete.ChangeState(EntityState.Unchanged);
            // Method to generate tsql for deleting entities
            DeleteData(delete, tsql, dbParams);
        }

        var addedEntites = context.ObjectStateManager.GetObjectStateEntries(EntityState.Added);
        foreach (var add in addedEntites)
        {
            // Set state to unchanged - so entity framework will ignore
            add.ChangeState(EntityState.Unchanged);
            // Method to generate tsql for added entities
            AddData(add, tsql, dbParams);
        }

        var editedEntites = context.ObjectStateManager.GetObjectStateEntries(EntityState.Modified);
        foreach (var edit in editedEntites)
        {
            // Method to generate tsql for updating entities
            UpdateEditData(edit, tsql, dbParams);
            // Set state to unchanged - so entity framework will ignore
            edit.ChangeState(EntityState.Unchanged);
        }
        if (!tsql.ToString().IsEmpty())
        {
            var dbcommand = Database.Connection.CreateCommand();
            dbcommand.CommandText = tsql.ToString();

            foreach (var dbParameter in dbParams)
            {
                var dbparam = dbcommand.CreateParameter();
                dbparam.ParameterName = dbParameter.Key;
                dbparam.Value = dbParameter.Value;
                dbcommand.Parameters.Add(dbparam);
            }
            var results = dbcommand.ExecuteNonQuery();
        }
    }
}

为什么我们在更新后将实体设置为未修改,因为您可以

var changed properties = edit.GetModifiedProperties();

获取所有已更改属性的列表。 由于所有实体现在都标记为未更改,因此EF将不会向SQL发送任何更新。

您还需要弄乱元数据,以便从实体到表,从属性到字段。 这并不是很难,但是弄乱元数据确实需要一些时间来学习。 有时我仍在挣扎。 我将所有内容重构为IMetaDataHelper接口,在其中将其传递给实体类型和属性名称以获取表和字段-以及缓存结果,因此我不必一直查询元数据。

最后,tsql是一个批处理,它具有所有T-SQL,包括锁定提示并包含事务级别,这是我们想要的方式。 如果用户也将数字字段更新为2,则我们也将数字字段从刚设置为nfield = 10更改为nfield = nfield + 2(在TSQL中),也避免了并发问题。

一旦有人开始编辑您的实体,您将无法锁定SQL,但是我也看不到如何通过存储过程来实现。

总而言之,我花了大约2天的时间才能完成所有准备工作。

  ask by Caribou translate from so

未解决问题?本站智能推荐:

2回复

实体框架中的存储过程

我已经在实体框架中添加了存储过程,并且也将功能导入了edmx中。 是否必须将所有三个功能插入,更新和删除功能添加到表中。 我曾经尝试过单独使用insert,也尝试使用全部插入,但是为什么我不能在连接字符串中得到存储过程的名称。 让我知道我清楚地做了什么。 我已经添加了sp
1回复

如何使用实体框架调用包含动态SQL的存储过程

我正在使用Entity Framework从SQL Server获取数据。 我有一个存储过程,其中包含用于搜索数据的动态SQL。 我的SQL代码如下所示: 我从ASP.NET MVC将此存储过程SPDynamic1 ,如下所示: 在这里,查询返回int 。 如何调用程序
1回复

这是在实体框架4中使用存储过程的推荐方法吗?

我的代码正在执行两次数据库往返操作,因为我不确定这是否是创建POCO集合的正确方法,其中由于某些特定的SQL代码,在第一次往返操作触及存储过程的情况下。 情境 用户在UI中输入一些“ 自动完成”搜索查询。 我的代码命中了一个存储过程(这是利用F * ull Text Search
1回复

为什么在实体框架中使用参数调用SP以返回多个结果集会引发错误

我有一个存储过程,该过程具有2个输入参数并返回多个 结果集。 在实体框架中,我将按以下方式调用此存储过程。 我正在使用msdn的本教程。 https://msdn.microsoft.com/zh-CN/library/jj691402(v=vs.113).aspx
1回复

实体框架-> Execute和LIKE子句

将需要执行类似操作的参数传递到存储过程时,我遇到了一个小问题。 这是我到目前为止的代码如下: 我的存储过程where子句如下所示: 如您所见,我尝试以不同的方式编写SQL,以允许用户不传递任何内容和传递某些内容。 我似乎没有用C#或SQL进行的工作似乎都没有用,是否有
1回复

使用存储过程实体框架从表中获取列表

我在条件库中使用相同的存储过程来插入和获取数据。 存储过程 就像使用实体框架插入数据一样,我正在这样做- 注意:这里的条件是1,所以它会插入数据过程。 尝试获取列表- 我尝试了这种从表中获取数据的方法,在该表中我必须将必要的参数传递给此过程调用。 尽管我只想
1回复

在实体框架中调用存储过程后返回所有行

在数据库中创建了以下存储过程,该存储过程在数据库中可以正常工作: 使用以下命令,我想从C#程序运行存储过程: 但是运行后,所有现有行都从数据库中显示出来。 另外,我使用以下方式来运行存储过程。 但是再次显示所有行: 如何解决搜索者问题?
6回复

实体框架调用存储过程需要未提供的参数

我通过这样的实体框架调用我的SP: 并得到错误 过程或函数“ super_group”需要未提供的参数“ @orderbyUnique”。 如您在上面看到的,我正在提供它。 这是存储过程: 任何想法为什么我会收到此错误?
3回复

对于实体框架中的所有情况,存储过程返回-1

我已创建此Stored Procedure并使用实体框架调用此Stored Procedure 。 下面是用C#编写的代码。 spIsValidUser Stored Procedure在所有情况下都返回-1 。 请告诉我错误。 编辑 - 根据给定的答案,存储过程不使用ret
1回复

切换FMTONLY是否会影响性能。 内部存储过程? (实体框架)

我正在建立一个动态查询,并尝试使用sp_executesql执行它。 我正在使用EF(实体框架)作为我的ORM工具。 如我所读,实体框架最初首先将FMTONLY设置为OFF ,然后仅请求该sql过程的元数据。 我不知道在sql中使用set fmtonly的影响 , 如果仅在创建复杂类型