John John
John John

Reputation: 1

How EF will get the system generated ID of a newly added object

I am working on an asp.net mvc5 web application + i am using EF6.0. and sometimes i can not understand how EF handles things internally. for example i have two entities named; Technology & Rack. where the Technology.TechnologyID is a system generated ID , while the Rack.RackID is user defined key and will be = to the Technology.TechnologyID. .so i have the following method to add a new technology , then to add a new rack and assign the Rack.RackID to be equal to the system generated Technology.TechnologyID.

    Technology technology = new Technology
                    {
                        IsCompleted = false,
                        IsDeleted = true,
                        TypeID = technologyypeID,
                        Tag = "CAB" + max.ToString(),
                        PartialTag = max,
                        StartDate = DateTime.Now,
                        IT360ID = dbresource.RESOURCEID,//,,
                        IsManaged = rj.Technology == null ? true : rj.Technology.IsManaged


                    };



                    rj.Rack.RackID = technology.TechnologyID;
SAVE():

now at the beginning i though that i above will not work , since when i try:-

rj.Rack.RackID = technology.TechnologyID;

the TechnologyID will not be available at this time, and using VS i found that at run time the TechnologyID will be equal to zero :-

enter image description here

so i am not sure how EF handle this ? and it force the Rack.RackID to be equal to the Technology.TechnologyID , although at run-time the technology-id will be zero. here is the sql statement that have been generated from the sql profiler :-

exec sp_executesql N'insert [dbo].[Racks]([RackID], [DataCenterID], [ZoneID], [IT360SiteID])
values (@0, @1, @2, @3)
select [timestamp]
from [dbo].[Racks]
where @@ROWCOUNT > 0 and [RackID] = @0',N'@0 int,@1 int,@2 int,@3 bigint',@0=128,@1=3,@2=2,@3=4 

not sure how the 128 was assigned altohugh at run time the value was zero?

Upvotes: 0

Views: 184

Answers (2)

Colin
Colin

Reputation: 22595

You have created a new Technology object and its TechnologyID is database generated. When it is inserted, EF follows the insert with a select to retrieve the generated value. Something like this:

DECLARE @TechnologyID int
SELECT @TechnologyID = [TechnologyID]
FROM [dbo].[Technology]
WHERE @@ROWCOUNT > 0 AND [TechnologyID] = scope_identity()

The results are then used by Entity Framework to fix up the Technology entity, so that when you then insert the Rack object, its RackID (which is not database generated) is correctly set to the new TechnologyID (as you specified in your code). The @0 parameter used when the select is issued on the Racks table to retrieve the timestamp is also set to the new value (128 in your example).

Upvotes: 1

Mike G
Mike G

Reputation: 174

When you're making your assignment rj.Rack.RackID = technology.TechnologyID; your new technology object has not yet been committed to the database, and thus won't have an assigned TechnologyID property. Without changing your mappings/schema, the simplest way to address your problem would be to save once to commit technology and assign it a TechnologyID, assign that as your RackID, and then save again.

The longer, more proper solution, would be to have RackID be an actual identity property, and instead use a foreign-key relationship from Rack to Technology with the appropriate EF mappings.

Upvotes: 0

Related Questions