为什么我在Entity Framework和SQL Server事务中得到不同的结果?

时间:2016-11-06 14:53:36

标签: c# sql-server entity-framework

在我的EF代码和SQL Server中,我尝试在此用户不存在时插入用户数据,但EF将其插入1000次,在SQL Server中只插入一次。

EF代码:

static void Main(string[] args)
{
    using (var db = new MyDbContext())
    {
        for (var i = 0; i < 1000; i++)
        {
            var count = db.Users.Count(f => f.Name == "Test");
            if (count > 0) continue;

            db.Users.Add(new User
            {
                Name = "Test",
                Gender = "Male",
                Phone = "1111111111",
                CreateTime = DateTime.Now
            });
        }

        try
        {
            db.SaveChanges();
            //1000 rows effected
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex.Message);
        }
    }

    Console.ReadKey();
}

T-SQL代码:

declare @i int = 0
begin tran

while(@i < 1000)
    begin
        if not exists (select 1 from [dbo].[User] where Name = 'Test')
            insert into [dbo].[User] values('Test','Male','1111111111',getdate())
        set @i = @i + 1
    end

if(@@ERROR > 0)
    rollback tran
else
    commit tran

即使我使用事务包装EF代码(但只调用SaveChanges一次),结果与受影响的1000行相同。

但是当我使用此代码时,结果与SQL Server中的结果相同:

using (var db = new MyDbContext())
{
    using (var trans = db.Database.BeginTransaction(ReadCommitted))
    {
        for (var i = 0; i < 1000; i++)
        {
            var count = db.Users.Count(f => f.Name == "Test");
            if (count > 0) continue;

            db.Users.Add(new User
            {
                Name = "Test",
                Gender = "Male",
                Phone = "1111111111",
                CreateTime = DateTime.Now
            });

            //1 row effected as sql does
            db.SaveChanges();
        }

        try
        {
            trans.Commit();
        }
        catch (Exception ex)
        {
            trans.Rollback();
            Console.WriteLine(ex.Message);
        }
    }
}

请告诉我为什么EF和SQL之间的交易不同

1 个答案:

答案 0 :(得分:4)

db.Users.Add未插入。它会在调用SaveChanges时进行插入(您认为SaveChanges做了什么,或者如果不是为了写出之前写的更改而需要它的原因?)。这就是db.Users.Count(f => f.Name == "Test")总是返回零的原因。

这与交易无关。

(顺便说一下,你可能应该在这里使用Any代替Count