UnitOfWork2 And Refetch

Posts   
 
    
Kirk
User
Posts: 22
Joined: 26-Apr-2004
# Posted on: 31-Mar-2006 23:31:53   

I seem to have a problem or at least misunderstanding with how refetch and UnitOfWork2 work. I have an entity E that has a collection of entity EF that is the middleman for a m:n relationship between entities E and F.

Code boils down to this:

e = new E(); f = new F(); uow.AddForSave(f); EF newEF = new EF(); newEF.E = e; newEF.F = f; e.EF.Add(newEF); uow.AddForSave(e, true);

The save works correctly. Order is f -> e -> newEF, but e is not refetched. When I have a case where f and newEF already exist and are not changed and do not need to be saved, but e is changed the prefetch works fine.

bclubb
User
Posts: 934
Joined: 12-Feb-2004
# Posted on: 01-Apr-2006 04:02:18   

So you are saying that after the uow is saved that e does not contain collection of ef entities? Are any othe new id's set by the database and guid's? These values cannot not be refetched when a new entity is saved and may cause your issue. What do you mean the prefetch works fine? Do you think you could post your code that works and the code that doesn't? Thanks.

Kirk
User
Posts: 22
Joined: 26-Apr-2004
# Posted on: 03-Apr-2006 18:14:35   

The collection of EF entities exists, but it the one EF entity in the collection says its out of sync. The entity E gets a new id value from the database via identity This value is present and correct in E. All other fields are marked out of sync.

After this is all done the values in the database all appear to be correct. For example E.Id=24, F.Id=16, EF.Id=22 EF.EId=24 EF.FId=16.

Sorry I meant refetch not prefetch.

The full amount of code is quite a bit. Do you really want me to post it here, or send it another way. The code is common code so there really isn't a case that works or doesn't. What works or doesn't work is if an entity representing a m:n relationship (i.e. phone number) is present or not.

The following show SQL Server profiles of the problem:

--COMMIT FROM UnitOfWork2 where the refetch does not get done. Notice F and EF saves

----SAVE OF F

declare @p3 bigint set @p3=17 exec sp_executesql N'INSERT INTO [PTCDB].[dbo].[tbl_Phone] ([PhoneTypeId], [Number], [Extension]) VALUES (@PhoneTypeId, @Number, @Extension);SELECT @Id=SCOPE_IDENTITY()',N'@Id bigint output,@PhoneTypeId int,@Number nvarchar(50),@Extension nvarchar(50)',@Id=@p3 output,@PhoneTypeId=2,@Number=N'8888888888',@Extension=N'88' select @p3

----EXTRANEOUS (not represented in original description of problem - save of an address)

declare @p3 bigint set @p3=34 exec sp_executesql N'INSERT INTO [PTCDB].[dbo].[tbl_Address] ([AddressTypeId], [Line1], [Line2], [City], [State], [PostalCode], [Country]) VALUES (@AddressTypeId, @Line1, @Line2, @City, @State, @PostalCode, @Country);SELECT @Id=SCOPE_IDENTITY()',N'@Id bigint output,@AddressTypeId int,@Line1 nvarchar(50),@Line2 nvarchar(50),@City nvarchar(50),@State nvarchar(50),@PostalCode nvarchar(20),@Country nvarchar(50)',@Id=@p3 output,@AddressTypeId=1,@Line1=N'fasfdasf',@Line2=N'asdfdsaf',@City=N'sadfsdf', @State=N'asdfasdf',@PostalCode=N'111111111',@Country=N'USA' select @p3

----SAVE OF E

declare @p3 bigint set @p3=25 exec sp_executesql N'INSERT INTO [PTCDB].[dbo].[tbl_SpecimenCollector] ([Active], [Name], [PrimaryAddressId], [ShippingAddressId], [Email], [StateOnly], [PriceCategory], [Quality], [MobileInfoId]) VALUES (@Active, @Name, @PrimaryAddressId, @ShippingAddressId, @Email, @StateOnly, @PriceCategory, @Quality, @MobileInfoId);SELECT @Id=SCOPE_IDENTITY()',N'@Id bigint output,@Active bit,@Name nvarchar(50),@PrimaryAddressId bigint,@ShippingAddressId bigint,@Email nvarchar(50),@StateOnly bit,@PriceCategory char(1),@Quality char(1),@MobileInfoId bigint',@Id=@p3 output,@Active=1,@Name=N'322323',@PrimaryAddressId=34,@ShippingAddressId=34, @Email=N'232323',@StateOnly=1,@PriceCategory='9',@Quality='X',@MobileInfoId=NULL select @p3

----SAVE OF EF

declare @p3 bigint set @p3=17 exec sp_executesql N'INSERT INTO [PTCDB].[dbo].[tbl_CollectorPhone] ([CollectorId], [PhoneId]) VALUES (@CollectorId, @PhoneId);SELECT @Id=SCOPE_IDENTITY()',N'@Id bigint output,@CollectorId bigint,@PhoneId bigint',@Id=@p3 output,@CollectorId=25,@PhoneId=17 select @p3

--COMMIT FROM UnitOfWork2 where the refetch appears to get done. Notice F and EF save not there because no phone was entered.

----EXTRANEOUS (not represented in original description of problem - save of an address)

declare @p3 bigint set @p3=35 exec sp_executesql N'INSERT INTO [PTCDB].[dbo].[tbl_Address] ([AddressTypeId], [Line1], [Line2], [City], [State], [PostalCode], [Country]) VALUES (@AddressTypeId, @Line1, @Line2, @City, @State, @PostalCode, @Country);SELECT @Id=SCOPE_IDENTITY()',N'@Id bigint output,@AddressTypeId int,@Line1 nvarchar(50),@Line2 nvarchar(50),@City nvarchar(50),@State nvarchar(50),@PostalCode nvarchar(20),@Country nvarchar(50)',@Id=@p3 output,@AddressTypeId=1,@Line1=N'sdafsda',@Line2=N'sadfsdaf',@City=N'asdfdsafsaf', @State=N'sadfsdaf',@PostalCode=N'111111111',@Country=N'USA' select @p3

----EXTRANEOUS (not represented in original description of problem - appears to be refetch of an address)

exec sp_executesql N'SELECT [PTCDB].[dbo].[tbl_Address].[Id], [PTCDB].[dbo].[tbl_Address].[AddressTypeId], [PTCDB].[dbo].[tbl_Address].[Line1], [PTCDB].[dbo].[tbl_Address].[Line2], [PTCDB].[dbo].[tbl_Address].[City], [PTCDB].[dbo].[tbl_Address].[State], [PTCDB].[dbo].[tbl_Address].[PostalCode], [PTCDB].[dbo].[tbl_Address].[Country] FROM [PTCDB].[dbo].[tbl_Address] WHERE ( ( [PTCDB].[dbo].[tbl_Address].[Id] = @Id1))',N'@Id1 bigint',@Id1=35

----SAVE OF E

declare @p3 bigint set @p3=26 exec sp_executesql N'INSERT INTO [PTCDB].[dbo].[tbl_SpecimenCollector] ([Active], [Name], [PrimaryAddressId], [ShippingAddressId], [Email], [StateOnly], [PriceCategory], [Quality], [MobileInfoId]) VALUES (@Active, @Name, @PrimaryAddressId, @ShippingAddressId, @Email, @StateOnly, @PriceCategory, @Quality, @MobileInfoId);SELECT @Id=SCOPE_IDENTITY()',N'@Id bigint output,@Active bit,@Name nvarchar(50),@PrimaryAddressId bigint,@ShippingAddressId bigint,@Email nvarchar(50),@StateOnly bit,@PriceCategory char(1),@Quality char(1),@MobileInfoId bigint',@Id=@p3 output,@Active=1,@Name=N'sadfdsfds',@PrimaryAddressId=35,@ShippingAddressId=35, @Email=N'asdfdsafdsf',@StateOnly=1,@PriceCategory='9',@Quality='X',@MobileInfoId=NULL select @p3

----REFETCH OF E

exec sp_executesql N'SELECT [PTCDB].[dbo].[tbl_SpecimenCollector].[Id], [PTCDB].[dbo].[tbl_SpecimenCollector].[Active], [PTCDB].[dbo].[tbl_SpecimenCollector].[Name], [PTCDB].[dbo].[tbl_SpecimenCollector].[PrimaryAddressId], [PTCDB].[dbo].[tbl_SpecimenCollector].[ShippingAddressId], [PTCDB].[dbo].[tbl_SpecimenCollector].[Email], [PTCDB].[dbo].[tbl_SpecimenCollector].[PrimaryFee], [PTCDB].[dbo].[tbl_SpecimenCollector].[HasCamera], [PTCDB].[dbo].[tbl_SpecimenCollector].[ClientPay], [PTCDB].[dbo].[tbl_SpecimenCollector].[AcceptClientPayMask], [PTCDB].[dbo].[tbl_SpecimenCollector].[PTCPay] AS [Ptcpay], [PTCDB].[dbo].[tbl_SpecimenCollector].[AcceptPTCPayMask] AS [AcceptPtcpayMask], [PTCDB].[dbo].[tbl_SpecimenCollector].[FaxConfirmation], [PTCDB].[dbo].[tbl_SpecimenCollector].[RefersPTC] AS [RefersPtc], [PTCDB].[dbo].[tbl_SpecimenCollector].[StocksSupplies], [PTCDB].[dbo].[tbl_SpecimenCollector].[IsSubContractor], [PTCDB].[dbo].[tbl_SpecimenCollector].[StateOnly], [PTCDB].[dbo].[tbl_SpecimenCollector].[PriceCategory], [PTCDB].[dbo].[tbl_SpecimenCollector].[Quality], [PTCDB].[dbo].[tbl_SpecimenCollector].[CouriersMask], [PTCDB].[dbo].[tbl_SpecimenCollector].[MobileInfoId] FROM [PTCDB].[dbo].[tbl_SpecimenCollector] WHERE ( ( [PTCDB].[dbo].[tbl_SpecimenCollector].[Id] = @Id1))',N'@Id1 bigint',@Id1=26

Walaa avatar
Walaa
Support Team
Posts: 14995
Joined: 21-Aug-2005
# Posted on: 04-Apr-2006 08:28:20   

Also please not that you used "uow.AddForSave(f);" without the boolean parameter. this may save the entire graph without refetching. Please note that Saves is done by the oreder you have specified. So either you remove this line or you add true as the last parameter.

Try the following:


e = new E();
f = new F();
//uow.AddForSave(f);
EF newEF = new EF();
newEF.E = e;
newEF.F = f;
//e.EF.Add(newEF); has no meaning as "newEF.E = e;" takes care of it
uow.AddForSave(e, true);

Kirk
User
Posts: 22
Joined: 26-Apr-2004
# Posted on: 04-Apr-2006 15:48:11   

Thank you. Your example removing the two statements worked great.