Reputation: 1
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 :-
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
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
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