Sam
Sam

Reputation: 10113

Entity Framework update based on database values?

Before Entity Framework, if I had something like a stock quantity or an on order quantity for a product, I would update it's quantities using the current database values as such:

UPDATE Products SET AvailableQty = AvailableQty - 2 WHERE ProductId = 1;

Is there a way to accomplish the same thing with Entity Framework? It seems like the framework follows a Load, Modify, Update pattern:

Product product = db.Products.FirstOrDefault(x => x.ProductId == 1);
product.AvailableQty += 2;
db.SaveChanges();

However, following this method there is a possibility that the product changes between the initial loading of the data and the update of the data. I know I can have a concurrency field on the entity that will prevent the update, but in most cases I don't want to have user intervention (such as a customer placing an order or receiving a purchase order).

Is there a preferred method to handling situations like these using EF, or should I just fall back to raw SQL for these scenarios?

Upvotes: 0

Views: 307

Answers (2)

Tarik
Tarik

Reputation: 11209

Enclose your find and update within a transaction

using (var transaction = new System.Transactions.TransactionScope())
{
    Product product = db.Products.FirstOrDefault(x => x.ProductId == 1);
    product.AvailableQty += 2;
    db.SaveChanges();
    transaction.Complete();
}

Upvotes: 2

Markus
Markus

Reputation: 761

"preferred method" would be opinion-based, so I'll just concentrate on the answer. EF allows you direct access to the database through the DbContext's Database property. You can execute SQL directly with ExecuteSqlCommand. Or, you can use the SqlQuery extension method.

ExecuteSqlCommand returns the records affected. And, the SqlQuery extension methods lets you use the fill provided by EF.

Also, if that is not enough power, you can create your own commands like this:

var direct = mydbContext.Database;
using (var command = direct.Connection.CreateCommand())
{
    if (command.Connection.State != ConnectionState.Open) 
    { 
        command.Connection.Open(); 
    }

    command.CommandText = query.ToString(); // Some query built with StringBuilder.
    command.Parameters.Add(new SqlParameter("@id", someId));
    using (var reader = command.ExecuteReader())
    {
        if (reader.Read()) 
        {
            ... code here ...
            reader.Close();
        }
        command.Connection.Close();
    }
}

Upvotes: 1

Related Questions