This is a migrated thread and some comments may be shown as answers.

Wrong results for 1:1 reference

6 Answers 118 Views
General Discussions
This is a migrated thread and some comments may be shown as answers.
This question is locked. New answers and comments are not allowed.
Igor
Top achievements
Rank 2
Igor asked on 22 Jul 2012, 09:39 AM
Hi,
i am using Telerik OpenAccess ORM 2012.2.607.1
Creating the empty domain model with MySQL backend in Visual Studio 2010 SP1 using Telerik ORM Designer (Create Domain Model -> Empty model, etc...).

Identity mechanism: HighLow
I've created User table and UserDetails table with 1:1 association (User can have 1 (One) instance of UserDetails), bind by  User.Id <---> UserDetails.Id.
All tables are mapped (using the "Map to table..." command).
The following script is being executed against DB to create the tables and constraints:

-- ConsoleApplication1.UserDetails
CREATE TABLE `user_details` (
    `id` integer NOT NULL,                  -- _id
    `email` varchar(255) NULL,              -- _email
    CONSTRAINT `pk_user_details` PRIMARY KEY (`id`)
) ENGINE = InnoDB;
 
-- ConsoleApplication1.User
CREATE TABLE `usr` (
    `user_name` varchar(255) NULL,          -- _userName
    `id` integer NOT NULL,                  -- _id
    CONSTRAINT `pk_usr` PRIMARY KEY (`id`)
) ENGINE = InnoDB;
 
-- OpenAccessRuntime.Relational.sql.HighLowRelationalKeyGenerator
CREATE TABLE `voa_keygen` (
    `table_name` VARCHAR(64) NOT NULL,
    `last_used_id` INTEGER NOT NULL,
    CONSTRAINT `pk_voa_keygen` PRIMARY KEY (`table_name`)
) ENGINE = InnoDB;
 
ALTER TABLE `user_details` ADD CONSTRAINT `ref_user_details_usr` FOREIGN KEY `ref_user_details_usr` (`id`) REFERENCES `usr` (`id`);

The following code is being executed after that:

EntitiesModel model = new EntitiesModel("Server=192.168.1.55;Database=test;Uid=user;Pwd=pass;");
 
model.Add(new User { UserName = "test 1" });
model.Add(new User { UserName = "test 2", UserDetails = new UserDetails { Email = "test2@email.tst" } });
 
model.SaveChanges();

So in mySQL database i got next data (represented as CSV):
Table "Usr"
user_name,id
"test 1",1
"test 2",2

Table "UserDetails"
id,email
1,"test2@email.tst"

When selecting the data with the C# code below:

EntitiesModel model = new EntitiesModel("Server=192.168.1.55;Database=test;Uid=user;Pwd=pass;");
User user = model.GetAll<User>().FirstOrDefault(x => x.UserName == "test 2");
UserDetails details = user.UserDetails; // ?? <--- details == null... why ??

i've got the user object instance created well, but the UserDetails property is equals to null.
In other hand, when i selecting the first record (id == 1) like that:
User user = model.GetAll<User>().FirstOrDefault(x => x.UserName == "test 1");
UserDetails details = user.UserDetails; // ?? <--- details are not null here

I've got details record, but it is not the expected behavior.
It's clear for me that there is an issue with Identity, so i've tried to put the Identity by hand (detials.Id = 2) when creating the details, but it does not work (It will put the value "1" to the Details table instead).

Could you please direct me to the right way to accomplish my goal? Thanks!
p.s. Attaching my project : http://www.4shared.com/zip/UGw6IzNa/ConsoleApplication1.html 

6 Answers, 1 is accepted

Sort by
0
Igor
Top achievements
Rank 2
answered on 24 Jul 2012, 05:54 AM
Guys, please help ! :(
0
Zoran
Telerik team
answered on 25 Jul 2012, 12:56 PM
Hello Igor,

 Thanks for reporting this issue to us. We did confirm a bug with the workflow you currently have and it is only related to objects that use the HighLow key generator. There is an easy workaround for your case though. The problem is related to the fact that the parent object (User) is not added to the context when the reference is being assigned. That said, here is a workaround:

EntitiesModel model = new EntitiesModel("Server=192.168.1.55;Database=test;Uid=user;Pwd=pass;");
 
model.Add(new User { UserName = "test 1" });
 
User user = new User { UserName = "test 2" };
 
UserDetails detail = new UserDetails { Email = "test2@email.tst" };

model.Add(user); 

user.UserDetails = detail;
 
model.SaveChanges();
 
User user2 = model.GetAll<User>().FirstOrDefault(x => x.UserName == "test 2");
UserDetails details = user2.UserDetails; // the details are now synchronized correctly.

The main point is that the user object is added to the context, before the UserDetails is assigned unlike the object-initializer assignment from your code.

Once again, thanks for helping us locate this bug, your Telerik points have been updated.Greetings,
Zoran
the Telerik team
OpenAccess ORM Q2'12 Now Available! Get your hands on all the new stuff.
0
Igor
Top achievements
Rank 2
answered on 25 Jul 2012, 03:23 PM
Zoran, thanks for answering i will try the workaround shortly
0
Andrey
Top achievements
Rank 1
answered on 26 Jul 2012, 04:47 AM
Unfortunately it does not work. The problem persisted.
0
Accepted
Andrey
Top achievements
Rank 1
answered on 26 Jul 2012, 05:07 AM
Here is a workaround:

Create Domain Class
User
{
    ID: Int32;
    UserName: String;
    UserDetails: UserDetails; //allow null
}

and
UserDetails
{
    ID: Int32;
    Email: String;
    User: User; //allow null
}

The following code works correctly:
User u1 = new User { UserName = "test 1", UserDetails = null };
model.Add(u1);
 
User u2 = new User { UserName = "test 2", UserDetails = new UserDetails { Email = "email 2" } };
u2.UserDetails.User = u2;
model.Add(u2);
 
User u3 = new User { UserName = "test 3", UserDetails = new UserDetails { Email = "email 3" } };
u3.UserDetails.User = u3;
model.Add(u3);
 
 
 
UserDetails ud1 = new UserDetails { Email = "email 1", User = null };
model.Add(ud1);
 
UserDetails ud4 = new UserDetails { Email = "email 4", User = new User { UserName = "user4" } };
ud4.User.UserDetails = ud4;
model.Add(ud4);
 
 
model.SaveChanges();
0
Igor
Top achievements
Rank 2
answered on 26 Jul 2012, 05:41 AM
i confirm that workaround mentioned by Andrey works for me.
Will be waiting for Telerik to fix the bug
Tags
General Discussions
Asked by
Igor
Top achievements
Rank 2
Answers by
Igor
Top achievements
Rank 2
Zoran
Telerik team
Andrey
Top achievements
Rank 1
Share this question
or