Adding and Updating with LINQ to Entities - rest

We are using L2E and REST in our project, and while I have been able to retrieve data from the db without issue, I am still not able to update or add new records to the db. I imagine that it's a syntax problem (we're still new to to linq), but I haven't been able to figure it out. We initially load the data in the dataservicecontext, and when updates are made they are stored in the CurrencyManager.Current of the binding source. However, when I call SaveChanges nothing gets modified in the db, and I don't know why.
For example,
Loading the data:
var customerQuery = Program.Proxy.Customers.Where(p => p.ContactId == g);
Saving the data:
Program.Proxy.SaveChanges();
I've confirmed that the updated copy of the entity in memory is being tracked, so I don't need to call AddObject, but I get an error ("The closed type Lynxphere.WindowsClient.LynxphereDataServices.Customers does not have a corresponding Customers settable property.") if I try to call AddLink. And I'm not even sure if this step is necessary. Help would be greatly appreciated.

Have a look on my repository pattern with a Save() function, published in the project below.
There is a EntityProductRepository implemented.
That might help you to do the Updates and Inserts correctly.
openticket.codeplex.com

Related

The correct HTTP method for resetting data

I want to "reset" certain data in my database tables using a RESTful method but I'm not sure which one I should be using. UPDATE because I'm deleting records and updating the record where the ID is referenced (but never removing the record where ID lives itself), or DELETE because my main action is to delete associated records and updating is tracking those changes?
I suppose this action can be ran multiple times but the result will be the same, however the ID will always be found when "resetting".
I think you want the DELETE method

breeze breeze.EntityQuery.from('Agencies'); returns the last entity returned for entire results

Let me start by saying i'm new to breeze so I apologize if this turns out to be a stupid error on my side.
I'm using angular specifically John Papa's hot towel base. I have create a repository that returns back a list of agencies from a WebApi2 service (backed by EF6). This code actually seems to work fine if i break point the return of the breeze httpget the records returned show all the correct entity data and count.
The problem is when they are returned to my angular callback from "... .execute().then" the number if items is correct but all the entities appear to be the last entity returned from the webapi.
I am using local storage again John Papa's zStorage. but even if i by pass the local call and force just a remote it's the same result.
So any ideas and what code snippets are needed to help resolve this?
Thanks for any help you can provide.
It turns out the issue was an error in camelCasing between the database, server and client. Once I got the "Id" fields all in sync things started working properly.

best practice when updating records using openJPA

I am wondering what the best practice would be for updating a record using JPA? I currently have devised my own pattern, but I suspect it is by no means the best practice. What I do is essentially look to see if the record is in the db, if I don't find it, I call the enityManager.persist(object<T>) method. if it does exist I call the entityManager.Merge(Object<T>) method.
The reason that I ask, is that I found out that the the merge method looks to see if the record is in the database allready, and if it is not in the db, then it proceeds to add it, if it is, it makes the changes necessary. Also, do you need to nestle the merge call in getTransaction().begin() and getTransaction.commit()? Here is what I have so far...
try{
launchRet = emf.find(QuickLaunch.class, launch.getQuickLaunchId());
if(launchRet!=null){
launchRet = emf.merge(launch);
}
else{
emf.getTransaction().begin();
emf.persist(launch);
emf.getTransaction().commit();
}
}
If the entity you're trying to save already has an ID, then it must exist in the database. If it doesn't exist, you probably don't want to blindly recreate it, because it means that someone else has deleted the entity, and updating it doesn't make much sense.
The merge() method persists an entity that is not persistent yet (doesn't have an ID or version), and updates the entity if it is persistent. You thus don't need to do anything other than calling merge() (and returning the value returned by this call to merge()).
A transaction is a functional atomic unit of work. It should be demarcated at a higher level (in the service layer). For example, transfering money from an account to another needs both account updates to be done in the same transaction, to make sure both changes either succeed or fail. Removing money from one account and failing to add it to the other would be a major bug.

Logical Delete from an EJB database

I have a database and the tables in this database are interconnected.
I am using seam and EJB to process data inside these tables in the database.
My backend database is postgres.
Now what I am trying to do is that I want to delete data from one table but I am getting a postgres sql error which tells me that I am violating rules.
I understand that I can delete this database logically
- A situation where I have to delete the database and set a flag.
But I don't know how to do this. I know this is simple but pardon me. I dont know it. Any help will be appreciative. Below is the code that I am using. Thank you for your help.
public void delete() throws java.sql.SQLException {
System.out.println("I got here FIRST");
user =em.find(Subscriber.class, subscriber.getId()); //ADDED LATER
users.remove(subscriber.getId());
em.remove(subscriber);
userList();
}
From what I can see at the first glance, is that you perhaps want to delete the user you are querying?
Thus, change em.remove(subscriber); to em.remove(user); //which you load from the find method
Update
Without know what kind of flag you want to check against, let me demonstrate how you can do this:
Lets assume User has a boolean field called disabled, and you want to only remove disabled users.
if(user.isDisabled())
em.remove(user);
So you only remove users if flag is true.

Get duplicate key exception when deleting and then re-adding child rows with Entity Framework

I'm using the Entity Framework to model a simple parent child relationship between a document and it's pages. The following code is supposed to (in this order):
make a few property updates to the document
delete any of the document's existing pages
insert a new list of pages passed into the method.
The new pages do have the same keys as the deleted pages because there is an index that consists of the document number and then the page number (1..n).
This code works. However, when I remove the first call to SaveChanges, it fails with:
System.Data.SqlClient.SqlException: Cannot insert duplicate key row in object 
'dbo.DocPages' with unique index 'IX_DocPages'.
Here is the working code with two calls to SaveChanges:
Document doc = _docRepository.GetDocumentByRepositoryDocKey(repository.Repository_ID, repositoryDocKey);
if (doc == null) {
doc = new Document();
_docRepository.Add(doc);
}
_fieldSetter.SetDocumentFields(doc, fieldValues);
List<DocPage> pagesToDelete = (from p in doc.DocPages
select p).ToList();
foreach (DocPage page in pagesToDelete) {
_docRepository.DeletePage(page);
}
_docRepository.GetUnitOfWork().SaveChanges(); //IF WE TAKE THIS OUT IT FAILS
int pageNo = 0;
foreach (ConcordanceDatabase.PageFile pageFile in pageList) {
++pageNo;
DocPage newPage = new DocPage();
newPage.PageNumber = pageNo;
newPage.ImageRelativePath = pageFile.Filespec;
doc.DocPages.Add(newPage);
}
_docRepository.GetUnitOfWork().SaveChanges(); //WHY CAN'T THIS BE THE ONLY CALL TO SaveChanges
If I leave the code as written, EF creates two transactions -- one for each call to SaveChanges. The first updates the document and deletes any existing pages. The second transaction inserts the new pages. I examined the SQL trace and that is what I see.
However, if I remove the first call to SaveChanges (because I'd like the whole thing to run in a single transaction), EF mysteriously does not do the deletes at all but rather generates only the inserts?? -- which result in the duplicate key error. I wouldn't think that waiting to call SaveChanges should matter here?
Incidentally, the call to _docRepository.DeletePage(page) does a objectContext.DeleteObject(page). Can anyone explain this behavior? Thanks.
I think a more likely explanation is that EF does do the deletes, but probably it does them after the insert, so you end up passing through an invalid state.
Unfortunately you don't have low level control over the order DbCommands are executed in the database.
So you need two SaveChanges() calls.
One option is to create a wrapping TransactionScope.
Then you can call SaveChanges() twice and it all happens inside the same transaction.
See this post for more information on the related techniques
Hope this helps
Alex
Thank you Alex. This is very interesting. I did indeed decide to wrap the whole thing up in a transaction scope and it did work fine with the two SaveChanges() -- which, as you point out, appear to be needed due to the primary key conflict with the deletes and subsequent inserts. A new issue now arises based on the article to which you linked. It properly advises to call SaveChanges(false) -- instructing EF to hold onto it's changes because the outer transaction scope will actually control whether those changes ever actually make it to the database. Once the controlling code calls scope.Complete(), the pattern is to then call EF's context.AcceptAllChanges(). But I think this will be problematic for me because I'm forced to call SaveChanges TWICE for the problem originally described. If both those calls to SaveChanges specify False for the accept changes parameter, then I suspect the second call will end up repeating the SQL from the first. I fear I may be in a Catch-22.