Stop linq from caching tables - c#

when a new entity in my database is created and then i request a table from the datacontext the new entity does not appear.
is linq caching the table and returning the cached version? if so how do i stop linq from doing this.
DALConnector.Dc.Order.InsertOnSubmit(NewOrder);
DALConnector.Dc.SubmitChanges();
now i click a button that shows a form with a gridview on it databound to DALConnector.Dc.Order which doesn't show the new order

How are you rebinding the grid? It does not cache the result, so I am not sure why that is an issue. You have to requery the context to get the new record... Or, if you are rebinding an object's records (like you are binding customers), you could get away with ensurihg the order is added to the Orders collection in the customer object, and not having to requery.
So if you are binding in this way:
grid.DataSource = customer.Orders;
You would only get the new order back if you did:
customer.Orders.Add(newOrder);
dc.Orders.InsertOnSubmit(newOrder);
dc.SubmitChanges();
And then, you could bind customer.Orders directly.

The Linq2Sql DataContext does not cache the complete Table, it only has a cache of the retrieved entities for change tracking purposes. If you would use a new DataContext for querying after you have inserted the order, your result will probably be the same.
AS you are using Linq2Sql, which can only be used with SQL Server, I recommend firing up the SQL Server Profiler and check if a real insert statement is submitted to the database in the first place.
Check your dbml, are you using runtime insert or a stored procedure for Order?
Also check if you're not swallowing any Exceptions the DataContext may raise on SubmitChanges().
If this does not help, please add your query code so we can verify it also.

Related

c# Edit bindingsource with linq datasource

I have a binding source who's datasource is the result from a linq query. I have several controls bound to this binding source. When the value of the controls is changed, how would I go about saving the value against the binding source and eventually the db?
Thanks
EDIT:
So my bindingSource is lined to a datasource like the following:
this.jobBindingSource.DataSource = jobDao.JobByJobNumber(jobNumber);
The query backed by the dao is:
return (from job in this.GetTable<Job>()
where job.Job_Number == jobNumber
select job).First();
LINQ queries usually return something that is readonly (if what the query returns still contains some context to the datasource this might be different - in that case there may be some way to commit changes made to an item)! You did not provide any details about what you are querying against, but this should also be the case for you.
Therefore you have to propagate changes to your data manually - manipulate the datasource you are querying against, at least changes can not be "written back up" through the LINQ query you bound the controls to.

Entity Framework not reload my UPDATED data

i have problem with visual studio or entity framework.
Situation is simple:
I have Employes, and i have data grid view for present, when i click on Edit employe, i get ID from employe
int employeID= Convert.ToInt32(dgvEmployes.SelectedRows[0].Cells[0].Value);
frmEditEmploye edit = new frmEditEmploye ();
edit.employ = new ePoliticsServis.Data.Employ();
edit.employ= eServis.Data.EmployesService.SelectEmployeById(employeID);
and i get Employe from db, and i load employe in new form for editing,and i save updated date, and go in database refresh table and all is good, all is updated, butproblem is, when i back on preview, datagrid view (datagrid is refreshed with new data, binding, all is ok) and again click on same employe for editing, i have form for editing but with old data, no with new upadated data from database for the same employe, when i shotdown my application and run again then i get new data refreeshed and updated. i really dont know where is problem..
I suspect the problem is your data context is retrieving the data from memory and not the database see a previous answer of mine for a possible solution.
Remember to surround your data context in a Using statement to correctly dispose of it.
From your latest comment I can see you are probably not disposing of your context correctly, I think this is called 'connection' in your code. This is probably a member variable of the class,
You'll probably need to change the method to something like this:
//You need to check the type Connection is and use it here. I'm using 'Connection' because I don't know the name of your context.
Using (var myContext = new Connection())
{
var returnValue = myContext.dm.epsp_Employ_SelectById(id).FirstOrDefault();
}
return returnValue;
One more thing...Check the database is being updated after you save the record. If it isn't you need to call SaveChanges().

Get Linq to SQL to save to the database

So I have the following code:
// Get the current user
_currentUser = WindowsIdentity.GetCurrent();
// Get the list of address for the current user
_dataMap = new DataMapDataContext();
_addresses = _dataMap.Addresses
.Where(address => address.InsertUserName == _currentUser.Name).ToList();
....
_addresses.Add(form.Item);
_dataMap.SubmitChanges();
When I call SubmitChanges nothing is saved in the database. Why is that? Am I missing the point? I thought with linq to sql you could just add items to your query results and then call SubmitChanges and it will work.... Clearly I am missing something.
Does it now work if you use "ToList"? If not then how do you insert stuff into the collection? (I don't think Add is part of IQueryable.)
Dont use _addresses.Add
You can't add directly to an IQueryable, you need to add it to the entity set.
Try this:
_dataMap.Addresses.InsertOnSubmit(form.Item);
_dataMap.SubmitChanges();
Of course, i can't see what form.Item is, but be aware it needs to be of the same Entity type as the _dataMap.Addresses entity set.
It makes no difference if you use .ToList().
With LINQ-SQL (unless you're using some sort of POCO mapping), you can't add items to a collection/query, you need to add the item directly into the Entity Set for the specified Data Context.
You can call .InsertOnSubmit as many times as you like, and .SubmitChanges will push all those INSERT's to the DB for you.
More info on InsertOnSubmit here.

Using Attach with Linq To Sql and Stored Procs

I am trying to use the attach method to update an entity that was retrieve via a stored proc.
The stored proc is set up to return a specific instance, which is present in my dbml. The retrieval works as expected and returns a fully populated object. The reason I need to use a stored proc is that I need to update a property on that entity at the same time that it is retrieved.
After I have retrieved this entity, I am mapping it using AutoMapper to another model which is used in another tier of the app. This tier performs a few operations, and makes a change to the entity, and passes it back to the repository for updating.
The repository converts this business model back into a database model, and attempts to attach it to the datacontext in order to take advantage of the automagic updating.
No matter what combination of Attach(entity, true) Attach(entity) etc, and it gives me messages like "Row not found or changed" or "Unable to add an entity with the same primary key".
Does anyone have any experience with the Attach method and how it can be used to update entities that did not necessarily come from the data context using query syntax (ie in this case a stored proc)?
Thanks alot
First, if you are creating a copy of the object, making changes and then trying to attach the copied object to the same DataContext as the one with the original object in it, then this would probably result in the "Unable to add an entity with the same primary key" message. One way to handle this is:
1. Get object from DataContext
2. Make changes and map object (or vice versa - whatever order)
3. Update the original object with the new values made in the other tier
4. SubmitChanges on the DataContext containing the original object
or
Get the object from a DataContext and close the DataContext
Make your changes and do your mapping
Retrieve the object from the DataContext to which you want to save
Update that object with the values from your mapped object
SubmitChanges
Alternately, when you say you are using the proc because you need to update a property at the same time that you retrieve it, I'd need to see the proc, but if you are somehow committing this update after retrieving the information, then indeed the message "row not found or changed" is correct. This would be hard to do, but you could do it if you're loading the data into a temp table, doing the update, and then using a select from the temp table to populate the object. One thing you could try is setting that property, in the L2S designer, to AutoUpdate = Never and see if that makes the problem go away. If so, this is your problem.
1: is it the same data-context, and
2: is it the same entity instance (or one that looks like it)
This would only happen for the same data-context, I suspect. If it is the same entity, then it is already there; just call SumbitChanges. Otherwise, either use a second data-context or detach the original entity.
So if I retrieved the entity via a stored proc, is it being tracked by the datacontext?
The thing is.. I'm going from the data model, to a another model that is used by another component, and then back. Its not.. really the same instance, but it does have all the same properties.
IE
public Models.Tag GetEntity()
{
var dbTag = db.PROJ_GetEntity((int)EntityStatuses.Created, (int)EntityStatuses.CreatingInApi).SingleOrDefault();
return FromDb Entity(dbEntity);
}
var appModel = GetEntity(); // gets an Entity from a stored proc (NOT GetEntity_RESULT)
appModel.MakeSomeChanges();
_Repo.Persist(appModel);
public void Persist(Models.AppModel model)
{
var dbEntity = Mapper.Map(model);
db.Attach(dbEntity);
db.SubmitChanges();
}
This is somewhat pseudo code like.. but it demostrates pretty much exactly what I am doing.
Thanks
I'm upvoting weenet's answer because he's right - you can't use Attach to apply the changes.
Unlike Entity Framework, you can only attach an L2S object to a datacontext if it has never been attached before - i.e. it's a newed entity that you want to Insert into a table.
This does cause numerous problems in multi-layered environments - however I've been able to get around many of the issues by creating a generic entity synchronisation system, which uses reflection and expression trees.
After an object has been modified, I run the dynamic delegate against a new object from the DC and the modified object, so that only the differences are tracked in the DC before generating the Update statement. Does get a bit tricky with related entities, though.

how to discard changes made to all linq tables?

I would like to discard all changes made to linq tables (this means -- I use linq, and data are changed on client side, the data on server are intact). How to do this?
EDIT: problem partially solved
http://graemehill.ca/discard-changes-in-linq-to-sql-datacontext/
It works as long as you don't use transaction. When you do and you use mixed "mode" for a record, there is a problem:
begin trans
insert a record
update inserted record
commit trans
When you update record as above Linq counts it as updated record, and in case of exception you have two actions -- transaction is rolled back and data on Linq side are discarded. On discard changes Linq tries to fetch it from the database (discard for update means refetching data for a record), but since all changes were rolled back, there is no records for update.
The question
How to improve DiscardChanges method in a smart general way to work with transactions. Or how to change the workflow of transactions/discard-submitchanges to make all those work together?
Those are not smart solutions:
refetching all data
recreating connection to DB (because it leads to (1))
To add to what Johannes said, I think the confusion here stems from thinking of the DataContext as something similar to a DataSet. It isn't.
A "table" in a DataContext is like a hint on how to retrieve a specific type of data entity from the database. Unlike a DataSet, the DataContext does not actually "contain" data, it simply tracks the discrete entities you've pulled out of it. If the DataContext disappears (is disposed), the entities are still valid, they are simply detached. This is different from a DataSet where the individual DataTables and DataRows are essentially bound to their containers and cannot outlive them.
In order to use the Refresh method of a DataContext, you need to use it on an actual entity or collection of entities. You can't "Refresh" a Table<T> because it's not actually a physical table, it's just a kind of reference.
Changes to entities connected to a DataContext are only persisted when you call the SubmitChanges method. If you dispose of the DataContext, there is absolutely no way that the changes can persist unless you manually reattach the detached entities to a new DataContext.
Simply discard the current DataContext without calling SubmitChanges() and get a new one.
Example:
DataContext myOldDc = new DataContext();

Categories

Resources