12

Is there a way to send a property with defaultValue but update it with the database computed result? There's a trigger in database, that for input -1 triggers a procedure which computes a new value. How to get the value back?

<Property Name="ID" Type="int" Nullable="false" StoreGeneratedPattern="None" DefaultValue="-1" />

var x = new Stuff();
db.Stuff.AddObject(x);
db.SaveChanges();
return x.ID //gives -1, but the computed value should be different.
Jan Matousek
  • 956
  • 3
  • 13
  • 15
  • I've tried db.Refresh(System.Data.Objects.RefreshMode.StoreWins, x); but with no luck, the refresh method probably searches the database using ID, which is the value I need to refresh. – Jan Matousek Sep 05 '12 at 12:00

6 Answers6

18

You need to reload the entity after savechanges.Because it has been altered by a database trigger which cannot be tracked by EF. SO we need to reload the entity again from the DB,

var x = new Stuff();
db.Stuff.AddObject(x);
db.SaveChanges();
db.Entry(x).GetDatabaseValues();

return x.ID;
Jayantha Lal Sirisena
  • 21,216
  • 11
  • 71
  • 92
  • 1
    I want only Identity Key value and GetDatabaseValues Load all fields of table. Is there any other way too load only identity key – Pratik 1020 Sep 09 '19 at 18:02
3

If you are using EF core it could be like this:

 public int CreateMyEntity(MyEntityType myEntity)
 {
      Microsoft.EntityFrameworkCore.ChangeTracking.EntityEntry<MyEntityType> created = _context.MyEntityType.Add(myEntity);
      _context.SaveChanges()
      return created.Entity.Id;
  }
ElConrado
  • 1,477
  • 4
  • 20
  • 46
2

I had the same problem, that my key would not update after calling SaveChanges and it would only return null for context.Entry(newObj).GetDatabaseValues().

In my case, setting StoreGeneratedPattern to Identity (on the key) in the EntityFramework model caused the key to update after calling SaveChanges.

BurnsBA
  • 4,347
  • 27
  • 39
1
using (var context = new EntityContext())
{
    var customer = new Customer()
    {
        Name = "John"
    };

    context.Customers.Add(customer);

    context.SaveChanges();      

    int id = customer.CustomerID;
}
Mohammad Dehghan
  • 17,853
  • 3
  • 55
  • 72
kastisk
  • 31
  • 2
  • 3
1

I'm using a data transfer object (DTO) to hide details of the data layer from the front end - then assigning values from it to the db object. My CustomerId is an identity which is automatically refreshed after SaveChanges() is called. No other method calls are needed. And since "customer" is a ref object, it is propagated to the front end.

public static void Add(DTO.Customer customer)
{
    MyEntities db = new MyEntities();

    var customerToAdd = new MyEntities.Data.Customer { Address = customer.Address, FirstName = customer.FirstName, LastName = customer.LastName, etc... };
    db.Customers.Add(customerToAdd);

    db.SaveChanges();
    customer.CustomerId = customerToAdd.CustomerId;
}
dotNetNerd
  • 11
  • 1
-3
   using (var context = new MyContext())
   {
       context.MyEntities.AddObject(newObject);
       context.SaveChanges();

       int id  = newObject.Id; // Will give u the autoincremented ID
   }
Developer
  • 759
  • 2
  • 9
  • 24