使用C#和SQL进行数据库提交后的错误结果。

问题描述 投票:0回答:1

我们所有的CRUD业务都有一个 CommitTransaction() 在返回Method的结果之前,在结尾处加上""。例如,我们有一个方法 Create() 的记录,如果没有带有 Status: 'Float'. 否则,它会选择记录并更新其内容。

这在数据库中检查是有效的。问题是,该方法返回的是之前的数据,而不是更新后的数据。

public class Sample
{
    public int ID {get; set;}
    public string Code {get;set;}
    public decimal Total {get; set;}
}

在... Create(), CodeTotal 是由用户输入的,它应该更新数据库中的数据。

例如

ID | Code     | Total
1  | CodeName | 100

用户更新

Code  : 'Code1'
Total : 200

但该方法仍然返回

Code  : 'CodeName '
Total : 100

但如果在数据库中检查,已经是

ID | Code     | Total
1  | Code1    | 200

我观察到,这种情况只发生在 CommitTransaction() 使用了不建议删除,但也需要一个正确的数据返回。

这里是一个简化的 Create():

private string procCRUD = "procCreate @ID={0},@Code={1},@Total={2}";

public Sample Create(Sample data)
{
  IQueryable<ComponentType> query = contextBase.Samples.FromSql(procCRUD,"create",data.ID, data.Code, data.Total); // contextBase.Samples is the DbContext

  commit(); // this commits the transaction

  return query;
}

procCRUD是一个存储过程。

DROP PROCEDURE IF EXISTS procCreate
GO

CREATE PROCEDURE procCreate
    @proc                               varchar(20) = 'create',          
    @ID                                 bigint = 0,               
    @Code                               varchar(20)= NULL,      
    @Total                              int= 0   
AS
BEGIN
    SET NOCOUNT ON;

    DECLARE @SQL varchar(MAX)
    SET @SQL = ''

    IF (@proc='create') BEGIN
        IF (NOT EXISTS(SELECT ID FROM Sample WHERE Status='Float')) 
        BEGIN
            INSERT INTO Sample(Code, Total) VALUES( @Code, @Total)
            SET @ID = @@IDENTITY;
        END
        ELSE 
        BEGIN
            SELECT @ID=ID FROM Sample WHERE Status='Float'

            UPDATE Sample SET 
                 Code = @Code
                ,Total = @Total
            WHERE ID=@ID
        END
    END

    SET @SQL = 'SELECT TOP 1 * FROM Sample '
    EXEC SP_EXECUTESQL @SQL
END
GO

我曾试过在返回前手动设置返回值,如 query.Code = data.Code 但如果我有10个以上的类属性,就会很耗时。另外,有些属性不是由用户输入的,而是从数据库中检索的,这取决于另一个属性的输入。

我不知道你们中是否有人也遇到了这个问题。任何帮助都将被感激。谢谢您的帮助。

(编辑)

c# sql commit
1个回答
1
投票

你需要更好地解释你正在尝试做什么,以及你背后的实际代码是什么。

contextBase.Samples.FromSql

至少,根据你的(不完整的)描述,以下内容似乎是相关的。

从base复制到parent。

我曾试过手动设置返回值,如 query.Code = data.Code 但如果我有10个以上的Class属性,这很耗时。

请阅读已经提出的解决方案 此处.你将最终定义一个 Map 扩展和使用

query.Map(data);

以上应该可以解决你的实际问题,但你的问题中还有其他不一致的地方,可能会影响结果。

SQL

procCRUD 是一个存储过程。

    SET @SQL = 'SELECT TOP 1 * FROM Sample '
    EXEC SP_EXECUTESQL @SQL
END
GO

在你的存储过程的最后,你管理了一个选择,以返回正确的值,但是,就我看来,你缺少了正确的where条件,比如说 WHERE ID=@ID (或 Status='Float',我不知道你的应用逻辑)。)

对了,你应该只 Commit() 在...之后 BeginTransaction但在你的问题中没有显示出来。


0
投票

你的描述没有任何意义。按照你的说法,你。

  • 做一个选择
  • 进行交易
  • 返还
  • 返回的值和数据库中的值不一致?

如果你想在更新或插入操作的过程中返回值,那么在更新或插入操作的过程中,可以使用 只是 SQL中可靠的语法是OUTPUT。https:/docs.microsoft.comen-ussqlt-sqlqueriesoutput-claus-transact-sql。

返回受INSERT、UPDATE、DELETE或MERGE语句影响的每条记录的信息,或基于这些信息的表达式。这些结果可以返回给处理应用程序,用于诸如确认消息、归档和其他此类应用程序的要求。这些结果也可以插入到表或表变量中。此外,您还可以在嵌套的INSERT、UPDATE、DELETE或MERGE语句中捕获OUTPUT子句的结果,并将这些结果插入到目标表或视图中。

例如,如果你--想获得刚刚插入的东西的主键。OUTPUT Inserted.ID 是唯一能可靠工作的方法。不幸的是,大多数非MSSQL DBMS没有这样的功能。

© www.soinside.com 2019 - 2024. All rights reserved.