Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/310.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# 使用实体框架更新时获取“插入”输出_C#_Entity Framework_Tsql_Entity Framework 6 - Fatal编程技术网

C# 使用实体框架更新时获取“插入”输出

C# 使用实体框架更新时获取“插入”输出,c#,entity-framework,tsql,entity-framework-6,C#,Entity Framework,Tsql,Entity Framework 6,SQL Server使用“inserted”关键字为插入和更新的记录提供输出 我有一个表示处理队列的表。我使用以下查询锁定记录并获取锁定记录的ID: UPDATE TOP (1) GlobalTrans SET LockDateTime = GETUTCDATE() OUTPUT inserted.ID WHERE LockDateTime IS NULL 这将输出一个名为ID的列,其中包含所有已更新的记录ID,在我的示例中为单个ID。如何将其转换为EF in C以执行更新并获取ID?实体框架

SQL Server使用“inserted”关键字为插入和更新的记录提供输出

我有一个表示处理队列的表。我使用以下查询锁定记录并获取锁定记录的ID:

UPDATE TOP (1) GlobalTrans
SET LockDateTime = GETUTCDATE()
OUTPUT inserted.ID
WHERE LockDateTime IS NULL

这将输出一个名为ID的列,其中包含所有已更新的记录ID,在我的示例中为单个ID。如何将其转换为EF in C以执行更新并获取ID?

实体框架无法做到这一点

通过选择所有记录,设置它们的LockDateTime并将它们写回,您可以通过ORM的方式完成。对于您想要做的事情来说,这可能是不安全的,因为默认情况下,这不是一个单独的事务

您可以跨越自己的事务,并将其用作隔离级别。这应该行得通。不过,根据数据库在后台所做的工作,这可能有些过分

您可以编写SQL。这违背了实体框架的目的,但就锁定机制而言,它应该和以前一样安全

还可以将其放入存储过程中。它比上面的版本好一点,因为至少有人会编译它并检查表名和列名是否正确。

获取数据表的简单示例1:

我这样做是直接针对连接的: 将command.ExecuteOnQuery更改为command.ExecuteReader

        var connection = DbContext().Database.Connection as SqlConnection;

        using (var command = connection.CreateCommand())
        {
            command.CommandText = sql;
            command.CommandTimeout = 120;
            command.Parameters.Add(param);

            using (var reader = command.ExecuteReader())
            {
                var resultTable = new DataTable();
                resultTable.Load(reader);
                return resultTable;
            }
        }
仅供参考,如果SQL中没有OUTPUT子句,它将返回一个空数据表

示例2返回实体:

这有点复杂,但确实有效。 使用插入输出的SQL语句*

         var className = typeof(T).Name;
         var container = ObjContext().MetadataWorkspace.GetEntityContainer(UnitOfWork.ObjContext().DefaultContainerName, DataSpace.CSpace);
         var setName = (from meta in container.BaseEntitySets where meta.ElementType.Name == className select meta.Name).First();

         var results = ObjContext().ExecuteStoreQuery<T>(sql, setName, trackingEnabled ? MergeOption.AppendOnly : MergeOption.NoTracking).ToList();

T作为正在处理的实体

为什么不使用触发器?您是否通过该unity连接到mssql数据库?我个人认为,我将使用存储过程方法。我总是鼓励应用程序和数据层不耦合到任何可能的程度。存储过程允许您对插入应用任意和自定义逻辑,并可以批量管理它们。