数据库操作预计会影响 1 行但实际上影响了 0 行 entity framework

Database operation expected to affect 1 row(s) but actually affected 0 row(s) with entity framework

我有以下 table:

我有以下触发器:

CREATE TRIGGER check_insertion_to_pushes_table
    BEFORE INSERT
    ON "Pushes"
    FOR EACH ROW
EXECUTE PROCEDURE trg_insert_failed_push();

CREATE or replace FUNCTION trg_insert_failed_push()
    RETURNS trigger AS
$func$
BEGIN
    IF (NEW."Sent" = false) THEN
        IF EXISTS(
                SELECT *
                FROM "Pushes"
                where "Sent" = false
                  and "CustomerId" = NEW."CustomerId"
                  and "PushTemplateId" = NEW."PushTemplateId"
            )
        THEN
            RETURN NULL;
        END IF;
        RETURN NEW;
    ELSE
        RETURN NEW;
    end if;
END
$func$ LANGUAGE plpgsql;

如果数据库中有行 CustomerIdPushTemplateIdSent 等于新行并且 Sent 为 false 我想通过插入。

我有以下测试来检查它是如何工作的:

    public class Tests
    {
        private IPushRepository _pushRepository;
        [NUnit.Framework.SetUp]
        public void Setup()
        {
            var confBuilder = new ConfigurationBuilder();
            var configuration = confBuilder.AddJsonFile("/home/aleksej/projects/makeapppushernet/TestProject/appsettings.LocalToProdDb.json").Build();
            _pushRepository = new PushRepository(new ApplicationDbContext(configuration));

        }

        [Test]
        public async Task Test1()
        {
            var push = new Push
            {
                CustomerId = 69164,
                Sent =  false,
                PackageId = "com.kek.lol",
                Category = "betting",
                Advertiser = "Advertiser",
                TemplateType = "opened_and_not_registration",
                IntervalType = "minutes",
                BottomDateTimeBorder =  90,
                TopDateTimeBorder = 60,
                ClientStartDateTime = DateTime.Now,
                FCMResponse = "hello",
                CreatedAt = DateTime.Now,
                LangCode = "En",
                PushBody = "Hello",
                PushTitle = "Hello",
                PushTemplateId = 15 
            };

            var pushesList = new List<Push>
            {
                push
            };

            await _pushRepository.SaveAsync(pushesList);

            Assert.Pass();
        }
    }

如果我在测试中为 Sent 设置 false,我会出现以下异常:

Database operation expected to affect 1 row(s) but actually affected 0 row(s). Data may have been modified or deleted since entities were loaded. See http://go.microsoft.com/fwlink/?LinkId=527962 for information on understanding and handling optimistic concurrency exceptions.

如果我设置true我什么都没有。它只是通过插入。

更新

好的,在 Shay Rojansky 的回答的帮助下,我有以下触发代码:

CREATE TRIGGER check_insertion_to_failed_pushes_table
    BEFORE INSERT
    ON "FailedPushes"
    FOR EACH ROW
EXECUTE PROCEDURE trg_insert_failed_push();

CREATE or replace FUNCTION trg_insert_failed_push()
    RETURNS trigger AS
$func$
DECLARE
    push        "FailedPushes"%ROWTYPE;
    old_push_id numeric;
BEGIN
    old_push_id = (SELECT "FailedPushId"
                   FROM "FailedPushes"
                   where "CustomerId" = NEW."CustomerId"
                     and "PushTemplateId" = NEW."PushTemplateId");
    push := new;

    IF (old_push_id != 0)
    THEN
        push."FailedPushId" = old_push_id;

        DELETE
        FROM "FailedPushes"
        where "CustomerId" = NEW."CustomerId"
          and "PushTemplateId" = NEW."PushTemplateId";

        return push;
    END IF;

    push."FailedPushId" = (SELECT count(*) FROM "FailedPushes")::numeric + 1;

    return push;
END
$func$ LANGUAGE plpgsql;

也许不是很优雅,但它确实有效。

您实际上是在将 PostgreSQL 配置为在某些情况下忽略 INSERT,但 EF Core 不会以任何方式意识到这一点。当您告诉 EF Core 添加新行时,它会期望在数据库中实际发生这种情况。如果实体有任何数据库生成的列(标识、序列),EF Core 还希望接收新插入行的值(并将它们填充回实体的 CLR 实例)。

所以据我所知,您不能只告诉数据库忽略 INSERT 并期望一切正常...

请参阅 this issue 关于 EF Core upsert 支持,这有点相关。

也许您的模型在控制器中解析为 Action 可能没有准确的值。