3

I am looking for a way to add manual raw SQL call to standard AppDbContext interaction. Say I have following code:

Message m = new Message
{
    Title = message.Title,
    Body = message.Body,
    Date = DateTime.Now,
    Foo = "foo"
};

_context.Messages.Add(m);
// Add some manual UPDATE SQL here, like:
// UPDATE SomeOtherTable SET Foo = 'Something' WHERE SomeComplex = 'Condition'

_context.SaveChanges();

The most important thing is to make that manual SQL part of command / transaction that gets created and executed as part of SaveChanges. If there is a way to inject my modification into SQL generated by SaveChanges - that's what I'm looking for.

2
  • Just wrap update query and SaveChanges within transaction. context.Database.BeginTransaction() and then transaction.Commit() Commented Apr 24, 2020 at 5:06
  • So every time you save any message you want to update some property of all messages in the table? Commented Apr 24, 2020 at 5:19

1 Answer 1

2

I use an overload for SaveChangesAsync on my DbContext base that accepts any arbitrary raw sql, the key is to wrap all the processing within a manually created transaction:

  public async Task<int> SaveChangesAsync(string customCommand,
        CancellationToken cancellationToken = default(CancellationToken),
        params object[] parameters)
    {
        using (var transaction = Database.BeginTransaction())
        {
            try
            {
                var result = await base.SaveChangesAsync(true, cancellationToken);

                await Database.ExecuteSqlCommandAsync(customCommand, parameters);
                transaction.Commit();

                return result;
            }
            catch (Exception ex)
            {
                transaction.Rollback();
                throw ex.Handle();
            }
        }
    }

Note: Handle() is an extension method where I transform the t-sql exceptions into my business exceptions, so that method is not relevant here.

Sign up to request clarification or add additional context in comments.

2 Comments

I am afraid that you must call transaction.Commit, but rollback will be executed automatically as part of transaction disposing if some of the queries fails.
This wraps everything in one batch locally but will still result in two trips to the server. No?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.