views:

289

answers:

1

I'm looking for a good guide into the right method of using Linq to Sql together with WPF.

Most guides only go into the bare basics like how to show data from a database but noone I found goes into how to save back to the database. Can you answer or point out to me a guide that can answer these questions.

I have a separate Data project because the same data will also be used in a web page so I have the repository method. That means I have a seperate class that uses the DataContext and there are methods like GetAllCompanies() and GetCompanyById ( int id ).

1) Where there are collections is it best to return as a IQueryable or should I return a list?

Inside the WPF project I have seen reccomendations to wrap the collection in a ObservabgleCollection.

2) Why should I use ObservableCollection and should I use it even with Linq / IQueryable

Some properties of the linq entities should be editable in the app so I set them to two-way mode. That would change the object in the observableCollection.

3) Is the object in the ObservableCollection still a instance of the original linq entity and so is the change reflected in the database ( when submitchanges is called )

I should have somekind of save method in the repository. But when should I call it? What happens if someone edits a field but decides not to save it, goes to another object and edits it and then press save. Doesn't the original change also save? When does it not remember the changes to a linq entity object anymore. Should I instance the Datacontext class in each method so it loses scope when done.

4) When and how to call the SubmitChanges method

5) Should I have the DataContext as a member variable of the repository class or a method variable

To add a new row I should create a new object in a event ( "new" button push ) and then add it to the database using a repo method.

6) When I add the object to the database there will be no new object in the ObservableCollection. Do I refresh somehow.

7) I wan't to reuse the edit window when creating new but not sure how to dynamically changing from referencing selected item from a listview to this new object. Any examples you can point out.

+1  A: 

A lot of questions! I will answer a few.

1) Use IQueryable whenever you wish to perform a LINQ query on it. Use of 'var' keyword instead of specifying a type is also preferred.

2) ObservableCollection provides notification mechanism whenever the number of items in the collection changes. That way a list control can refresh itself whenever a collection changes.

NOTE: you still need to implement INotifyPropertyChanged interface to notify property changes for individual objects in the collection.

3) I recommend not storing LINQ entities directly into the collection. Reason is if you want to propagate changes back to database, you must keep the DataContext open from which that entity was created. That keeps the connection open and is not advised.

4) Whenever you want to make changes in the database, create a new DataContext, select objects you want to change, change their properties and call SubmitChanges() method. Close the DataContext afterward.

5) As I said, create a new instance of DataContext whenever you want to select objects out of database or submit changes back to the database.

decyclone
So I should create ViewModel classes for every table in the database? Then when it's changed I have to get the original object again, change it to match the viewModel and then save it. That's a lot of code and seems to negate many of the good qualities of linq and WPF databinding.
Ingó Vals
That's right. But, to save some coding, you could use the LINQ entities as your Business Objects, but once you close the DataContext (which should be closed ASAP) they won't be able to propagate changes back to database. You will have to select a new object from new DataContext, copy all the properties from old to new one and call SubmitChanges().You could also look into the following links :http://www.codeproject.com/KB/linq/linq-to-sql-detach.aspxhttp://www.plinqo.com/ And http://www.plinqo.com/entity-enhancements.ashx
decyclone
Ok thinking about creating ViewModel classes for each and every entity/db-table. This ViewModel class could handle saving the object back to db for example. If I let these classes implement INotifyPropChange I don't need to put it into a ObservableCollection. Also I wan't them to inherits from some base class.Is this a design pattern that is commonly used and is there someplace I can read about it?
Ingó Vals
@Igno Vals : I think you are confusing Model with ViewModel. You need to create a Model class for each entity (not necessarily table) in the database and create a ViewModel for each View in your application. Secondly, you must use ObservableCollection if you want to update the ItemsControl anytime the number of items change in it and you must use INotifyPropertyChanged if you want to update values in controls whenever you change property values in your objects.
decyclone
I have a data layer, including a repository that uses LINQ to fetch data from the database. I wrap the objects there in my custom created objects that I then use in the WPF app. I call these objects ViewModels but they could be plain objects ( I think the datalayer counts as my Model part ). However a change is made to a object and I would like to save this change. As the user only has access to the ViewModel part should it have the save method wich interacts with the datalayer?
Ingó Vals
@Igno Vals : While using Repository pattern, saving the data is responsibility of a Repository and not the Model. So, your "ViewModel" should not have a Save() method but your Repository should which should save all the changed objects in it. Now, let me clear some confusion. A Model is a class/object used in Business Logic Layer and not Data Layer. A ViewModel in MVVM pattern is a wrapper over a Model with a set of bindable properties and commands that a View can bind to.
decyclone
For your reference :http://www.codeproject.com/KB/architecture/linqrepository.aspx |http://www.martinfowler.com/eaaCatalog/repository.html |http://msdn.microsoft.com/en-us/magazine/dd419663.aspx
decyclone
@decyclone: The connection is not kept open throughout the datacontext lifecycle. Datacontext is attached to the entities for tracking changes in each entity. and that's how it support lazy-loading from database for foreign records. so maintaining the life-cycle of entities is a problem. Recommended practice for DataContext lifecycle is to restrict it to unit-of-work.
this. __curious_geek