我们所有的 CRUD 操作在返回方法结果之前都有一个CommitTransaction()
。例如,我们有一个方法Create()
,如果没有具有Status: 'Float'
的现有记录,则创建记录。否则,它将选择记录并更新其内容。
这与数据库中的检查方式相同。问题是,该方法返回的是其以前的数据,而不是更新的数据:
public class Sample
{
public int ID {get; set;}
public string Code {get;set;}
public decimal Total {get; set;}
}
在Create()
中,Code
和Total
由用户输入,用户应该更新数据库中的数据。
例如
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 个类属性,则会很耗时。此外,某些属性不是由用户输入的,而是从数据库中检索的依赖于输入的另一个属性。
我想知道你们中的一些人是否也遇到过这个问题。任何帮助将不胜感激。谢谢。
(已编辑(
你需要更好地解释你正在尝试做什么以及你的背后的实际代码是什么
contextBase.Samples.FromSql
至少,根据您的(不完整(描述,以下内容似乎是相关的。
从基复制到父级。
我尝试手动设置返回值,例如
query.Code = data.Code
返回之前,但如果我有超过 10 个类属性,则会很耗时。
请阅读此处已经建议的解决方案。 您最终将定义一个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'
,我不知道您的应用程序逻辑(。
顺便说一下,您应该只在 BeginTransaction 之后Commit()
,但这不会显示在您的问题中。
你的描述中没有任何意义。根据你的说法,你:
- 执行选择
- 提交事务
- 返回值
- 想知道返回的值与数据库中的值不匹配?
如果要在更新或插入操作运行时检索值,则 SQL 中唯一可靠的语法是 OUTPUT: https://learn.microsoft.com/en-us/sql/t-sql/queries/output-clause-transact-sql
返回受插入、更新、删除或合并语句影响的每一行的信息或基于这些行的表达式。这些结果可以返回到处理应用程序,以用于确认消息、存档和其他此类应用程序要求。结果也可以插入到表或表变量中。此外,还可以在嵌套的 INSERT、UPDATE、DELETE 或 MERGE 语句中捕获 OUTPUT 子句的结果,并将这些结果插入到目标表或视图中。
例如,如果您想要获取刚刚插入的内容的主键,OUTPUT Inserted.ID
是唯一可靠工作的方法。不幸的是,大多数非MSSQL DBMS都没有这样的功能。