This question is locked. New answers and comments are not allowed.
Stefan Lorenz
Top achievements
Rank 1
Stefan Lorenz
asked on 29 Jul 2010, 09:22 AM
Hi,
I've designed a simple class MyData with a field "MyData_id" (INT32, Identity=True). Whether I select "Default" or "HighLow" as Identity Mechanism, if I create a new instance, it's MyData_id is 0. On calling SaveChanges() I get an DataStore-Exception (Insert of '1449231688-12' failed due to IDENTITY INSERT=OFF).
I used OA's HighLow-generator before with classic forward mapping and it ran out of the box, without messing around with identity insert. It should show the same behaviour using the domain model, right?
Thanks in advance
Stefan
I've designed a simple class MyData with a field "MyData_id" (INT32, Identity=True). Whether I select "Default" or "HighLow" as Identity Mechanism, if I create a new instance, it's MyData_id is 0. On calling SaveChanges() I get an DataStore-Exception (Insert of '1449231688-12' failed due to IDENTITY INSERT=OFF).
I used OA's HighLow-generator before with classic forward mapping and it ran out of the box, without messing around with identity insert. It should show the same behaviour using the domain model, right?
Thanks in advance
Stefan
11 Answers, 1 is accepted
0
Hi Stefan Lorenz,
Petar
the Telerik team
We tried to reproduce your problem but without luck. Is it possible for you to open a support ticked and send us a small project that recreates the problem you have encountered? This will greatly help us in solving the issue.
We are looking forward to your reply.
Petar
the Telerik team
Do you want to have your say when we set our development plans?
Do you want to know when a feature you care about is added or when a bug fixed?
Explore the
Telerik Public Issue Tracking
system and vote to affect the priority of the items
0
Daniel Plomp
Top achievements
Rank 2
answered on 11 Aug 2010, 09:30 PM
Hi,
I experience the same problem. With the classic way of ORM, after I did a commit, I could get the ID of my new inserted record.
Now I use the Domain Model and then after the SaveChanges() it won't work?
Here's the code of my function:
I experience the same problem. With the classic way of ORM, after I did a commit, I could get the ID of my new inserted record.
Now I use the Domain Model and then after the SaveChanges() it won't work?
Here's the code of my function:
public
int
SaveOffer(
int
offerid,
string
username,
int
materialid,
int
materialcompletionid,
int
washupid,
int
washupcraneholes,
int
hotplatesavingid,
int
kitchensetupid,
int
worktopbordertypeid)
{
Offer offer =
null
;
using
(SinedModelContext db =
new
SinedModelContext())
{
if
(offerid != 0)
{
// Update an existing offer
offer =
this
.GetOffer(offerid);
offer.DatetimeChanged = DateTime.Now;
}
else
{
// Create a new offer
offer =
new
Offer();
offer.DatetimeCreated = DateTime.Now;
offer.DatetimeChanged = DateTime.Now;
}
offer.Username = username;
offer.MaterialId = materialid;
offer.MaterialCompletionId = materialcompletionid;
offer.WashupId = washupid;
offer.WashupCraneHoles = washupcraneholes;
offer.HotPlateSavingId = hotplatesavingid;
offer.KitchenSetupId = kitchensetupid;
offer.WorkTopBorderTypeId = worktopbordertypeid;
db.SaveChanges();
}
// Return the offerid (is 0, instead of the new value???)
return
offer.OfferId;
}
0
Hi Daniel,
Damyan Bogoev
the Telerik team
You should slightly modify your code in order to make it work correctly:
1. Firstly, when you try to insert an object to the database you should use the OpenAccessContext.Add method. This method will mark the object for insertion and if the transaction is committed it will be inserted. The transaction is committed when the OpenAccessContext.SaveChanges method is called.
2. You should use one and the same OpenAccessContext instance for retrieving and editing an object. The OpenAccessContext manages the object’s state. If you try to use one context for retrieving the object and later another for persisting the changes to the database the changes will not be saved.
Now the code should look like this:
public
int
SaveOffer(
int
offerid,
string
username,
int
materialid,
int
materialcompletionid,
int
washupid,
int
washupcraneholes,
int
hotplatesavingid,
int
kitchensetupid,
int
worktopbordertypeid)
{
Offer offer =
null
;
using
(SinedModelContext db =
new
SinedModelContext())
{
if
(offerid != 0)
{
// Update an existing offer
offer =
this
.GetOffer(offerid, db);
// point #2
offer.DatetimeChanged = DateTime.Now;
}
else
{
// Create a new offer
offer =
new
Offer();
offer.DatetimeCreated = DateTime.Now;
offer.DatetimeChanged = DateTime.Now;
db.Add(offer);
// point #1
}
offer.Username = username;
offer.MaterialId = materialid;
offer.MaterialCompletionId = materialcompletionid;
offer.WashupId = washupid;
offer.WashupCraneHoles = washupcraneholes;
offer.HotPlateSavingId = hotplatesavingid;
offer.KitchenSetupId = kitchensetupid;
offer.WorkTopBorderTypeId = worktopbordertypeid;
db.SaveChanges();
}
// Return the offerid (is 0, instead of the new value???)
return
offer.OfferId;
}
// point #2
public
Offer GetOffer(
int
offerId, SinedModelContext db)
{
return
db.Offers.FirstOrDefault(o => o.OfferId == offerId);
}
You could find this help article useful, it demonstrates how to perform CRUD operations with Telerik OpenAccess ORM.
Hope you will find helpful the provided information. If any other questions arise please contact us back.
Damyan Bogoev
the Telerik team
Do you want to have your say when we set our development plans?
Do you want to know when a feature you care about is added or when a bug fixed?
Explore the
Telerik Public Issue Tracking
system and vote to affect the priority of the items
0
Daniel Plomp
Top achievements
Rank 2
answered on 12 Aug 2010, 08:38 PM
Hi Damyan,
Thanks for the reply. I understand what I forgot.
What would be the best practice for webapplications?
I used to work with the ScopeFactory solution and that worked well within my solution (DAL, BLL and UI).
I thought that with this new approach it would work out of the box (a little naive maybe :) )
For example: I use different repositories that are inside a seperate project. Also, I pass through objects to other functions, but then I also get the message about different scopes.
Is there already a solution for this?
Thanks,
Daniel
Thanks for the reply. I understand what I forgot.
What would be the best practice for webapplications?
I used to work with the ScopeFactory solution and that worked well within my solution (DAL, BLL and UI).
I thought that with this new approach it would work out of the box (a little naive maybe :) )
For example: I use different repositories that are inside a seperate project. Also, I pass through objects to other functions, but then I also get the message about different scopes.
Is there already a solution for this?
Thanks,
Daniel
0
Hi Daniel,
Damyan Bogoev
the Telerik team
1. You could find the following KB articles useful as they explain the best practices for dealing with the OpenAccessContext in a web application:
Another useful resource is this code library example “Implementing Context factory for Telerik OpenAccess ORM”.
2. You should always use the OpenAccessContext.Add method when you try to insert new object to the database otherwise Telerik OpenAccess ORM will not persist or track this entity for changes.
3. The only solution is to work with one and the same OpenAccessContext instance for retrieving and modifying an entity as I explained in point #2 from my previous post.
Hope you will find the provided information useful. If any other questions arise please do not hesitate to contact us back.
Damyan Bogoev
the Telerik team
Do you want to have your say when we set our development plans?
Do you want to know when a feature you care about is added or when a bug fixed?
Explore the
Telerik Public Issue Tracking
system and vote to affect the priority of the items
0
Daniel Plomp
Top achievements
Rank 2
answered on 18 Aug 2010, 01:37 PM
Hello Damyan,
Thanks for the reply.
I used the approach in Best Practices in web development with OpenAccess - Part Two
I have created the 'ContextFactory' class inside my Repository project and created a constructor inside each repository class that sets the current HttpContext.
Now should'nt I do anything to dispose the items inside the Context object?
If I would do everything within a web project, I would use this approach:
And I read that with this approach disposal is taking care of...
So, is my solution save?
Regards,
Daniel
Thanks for the reply.
I used the approach in Best Practices in web development with OpenAccess - Part Two
I have created the 'ContextFactory' class inside my Repository project and created a constructor inside each repository class that sets the current HttpContext.
public
class
ArticleRepository
{
protected
DataModelContext context;
public
ArticleRepository(HttpContext current)
{
context = ContextFactory.GetContextPerRequest(current);
}
public
Article GetArticle(
int
articleid)
{
try
{
return
context.Articles.Where(x => x.ArticleId == articleid).FirstOrDefault();
}
catch
(Exception ex)
{
throw
ex;
}
}
}
Now should'nt I do anything to dispose the items inside the Context object?
If I would do everything within a web project, I would use this approach:
using
(DataContext c =
new
DataContext)
{
...
}
And I read that with this approach disposal is taking care of...
So, is my solution save?
Regards,
Daniel
0
Hi Daniel,
Damyan Bogoev
the Telerik team
Yes, it is recommended to dispose the OpenAccessContext instance from the code behind. A good approach is to dispose the context within the Page_Unload method:
protected
void
Page_Unload(
object
sender, System.EventArgs e)
{
...
if
(context !=
null
)
{
context.Dispose();
}
}
Damyan Bogoev
the Telerik team
Do you want to have your say when we set our development plans?
Do you want to know when a feature you care about is added or when a bug fixed?
Explore the
Telerik Public Issue Tracking
system and vote to affect the priority of the items
0
Daniel Plomp
Top achievements
Rank 2
answered on 18 Aug 2010, 04:53 PM
Hi Damyan,
I'm not setting the context inside my page or masterpage, but in a seperate project. (as you can read in my previous post).
How should I convert the ScopeFactory method that was provided by telerik, to use it for the new context approach?
So in my webapplication I do this to make use of my repository:
Regards,
Daniel
I'm not setting the context inside my page or masterpage, but in a seperate project. (as you can read in my previous post).
How should I convert the ScopeFactory method that was provided by telerik, to use it for the new context approach?
So in my webapplication I do this to make use of my repository:
private
void
BindGrid()
{
try
{
OfferRepository rep =
new
OfferRepository();
this
.gridKitchenSetups.DataSource = rep.GetKitchenSetups();
this
.gridKitchenSetups.DataBind();
}
catch
(Exception ex)
{
throw
ex;
}
}
Regards,
Daniel
0
Hello Daniel,
Damyan Bogoev
the Telerik team
1. Here is the implementation of the ScopeFactory method which uses an OpenAccessContext object:
public
class
ContextFactory
{
public
static
YourContextName GetContextPerRequest(HttpContext httpContext)
{
if
(httpContext ==
null
)
{
return
new
YourContextName();
}
else
{
string
key = httpContext.GetHashCode().ToString(
"x"
) + System.Threading.Thread.CurrentContext.ContextID.ToString();
YourContextName context =
null
;
if
(httpContext ==
null
)
{
context =
new
YourContextName();
}
else
{
context = (YourContextName)httpContext.Items[key];
if
(context ==
null
)
{
context =
new
YourContextName();
httpContext.Items[key] = context;
}
}
return
context;
}
}
}
2. At first, I am sorry for the incorrect answer in my previous post. I recommend you using the following approach in order to be able to dispose the OpenAccessContext instance from the web application:
- Implement the IDisposable interface within the repository class;
- Dispose the OpenAccessContext instance in the IDisposable.Dispose() method:
public
class
RepositoryClass : IDisposable
{
...
public
void
Dispose()
{
this
.context.Dispose();
}
}
- Now you could use a repository instance in the following way:
using
(RepositoryClass repository =
new
RepositoryClass())
{
...
}
Hope that helps.
Damyan Bogoev
the Telerik team
Do you want to have your say when we set our development plans?
Do you want to know when a feature you care about is added or when a bug fixed?
Explore the
Telerik Public Issue Tracking
system and vote to affect the priority of the items
0
gmendez
Top achievements
Rank 1
answered on 09 Jun 2011, 06:06 PM
Hello, I'm also have the same problem. I think I'm doing things as suggested. Even this is a very simple scenario I can't figure out what's wrong.
I have 2 classes: Persona and Telefono (Person and Phone). A person can have one or many phones.
In both classes at the model designer I assigned Id properties of type int32 and set them to IsIdentity=true.
The first question is: Where is the key generator specified? I didn't find an option for that at the properties grid for the Id property.
The second question relates to the first in the sense that the first object I create has it's id set to 0, and so does all subsequent objects, thus, getting an exception after the first one was inserted. The first Telefono object has it's Id set to 0 too.
The third question is: No "voa_keygen" table was created. Is this Ok?
I'm new to the model approach, so any help will be very appreciated.
The code I'm testing is the following:
Thanks in advance,
Gonzalo
I have 2 classes: Persona and Telefono (Person and Phone). A person can have one or many phones.
In both classes at the model designer I assigned Id properties of type int32 and set them to IsIdentity=true.
The first question is: Where is the key generator specified? I didn't find an option for that at the properties grid for the Id property.
The second question relates to the first in the sense that the first object I create has it's id set to 0, and so does all subsequent objects, thus, getting an exception after the first one was inserted. The first Telefono object has it's Id set to 0 too.
The third question is: No "voa_keygen" table was created. Is this Ok?
I'm new to the model approach, so any help will be very appreciated.
The code I'm testing is the following:
private
void
btnCreate_Click(
object
sender, EventArgs e)
{
EntitiesModel context =
new
EntitiesModel();
Persona p =
new
Persona();
p.Nombre =
"Person Name"
;
p.FechaIngreso = DateTime.Today;
p.Notas =
"Some notes"
;
p.Telefonos.Add(
new
Telefono() { Numero =
"12345"
, Descripcion =
"Home"
, Persona = p });
context.Add(p);
context.SaveChanges();
}
Thanks in advance,
Gonzalo
0
gmendez
Top achievements
Rank 1
answered on 09 Jun 2011, 09:01 PM
Ok, found it.
I didn't realize I must set the generator type at the class level, not the property :)
I didn't realize I must set the generator type at the class level, not the property :)