linq to sql - What pattern to use for Data Access in WPF/MVVM App -


i have task management application uses class access data using linq-to-sql; want move data access separate solution in project. reason want in preparation 2 things. first create service run on database "server" (it win 7 pc) periodically query tasks , send out email reminders ones due. second change data access wcf can access tasks wp7 (once on verizon)

the tasks returned defined number of user controls bound viewmodel. iqueryable built in series of statements narrow down selection according databound members. query ordered other members. once move data access out of solution not have access viewmodels members need pass relatively large number of parameters , not sure correct way be. ways can think of are:

  1. simply create method dozen or more parameters (i told bad practice)
  2. create object contains parameters , pass (doesn't seem different first option me)
  3. create class in data access solution, , instantiate , set each of properties before calling method return iqueryable (or observablecollection) have read practice "smells bad"

i pretty green @ oop , wpf , simple app complicated have built. feel missing pattern or practice, suggestions?

a sample of how query being built:

iqueryable<issue> issuesquery;  // select items issuesquery = in db.issues       select i;  // filters out pending issues issuesquery = issuesquery.where(i => i.issispending == showpendingtasks);  // filters out closed issues if not shown if (includeclosedissues == false) {     issuesquery = issuesquery.where(i => i.issisclosed == false); }  // filters out regular tasks if not shown if (showtasks == false) {     issuesquery = in issuesquery              i.issisonstatusboard == true              select i; }  // more filters here  // order results       issuesquery = issuesquery.orderbydescending(     => i.ississticky).thenby(     i=>!i.issduedate.hasvalue).thenby(     => i.issduedate).thenby(     => i.issurgency);  // iqueryable returned converted observablecollection return issuesquery; 

i explain how use services, because mandatory in 3-tired architecture , separate model view nothing else can.

you can use 2 different solutions.

1. wcf dataservices.

add -> new item -> wcf data service.

then specify name of datacontext , set rights of access.

public class wcfdataservice1 : dataservice<testentities> {     public static void initializeservice(dataserviceconfiguration config)     {         config.dataservicebehavior.maxprotocolversion = dataserviceprotocolversion.v2;         config.setentitysetaccessrule("*", entitysetrights.all);         config.setserviceoperationaccessrule("*", serviceoperationrights.allread);     }      /// <summary>     /// example of custom operations     /// </summary>     [webget]     public iqueryable<item> itemsbyid(int id)     {         return this.currentdatasource.items.where(i => i.id == id);     } } 

in client application add new service reference , after can use service if local database:

var proxy = new testentities(new uri("http://localhost:8513/wcfdataservice1.svc/")); var items = proxy.items.where(i => i.id > 2 && i.title.contains("x1")); var item2 = proxy.execute<item>(new uri("itemsbyid?id=1", urikind.relative)).firstordefault(); 

advantage: don't need write numerous methods getitemsbyid, getitemsbyyear, gettenitems, etc; can create filter query on client's side.

disadvantages: service operations isn't statically typed; it's dificult call custom operations if thay have many parameters; there many problems if use custom objects instead of entities;

2. wcf services

add -> new item -> wcf service

repository class:

public class issuesrepository {     public static list<issue> getissues()     {         //creating new connection not cause overhead because there pool of connections         using (var db = new testentities())          {             list<expression<func<issue, bool>>> filters = new list<expression<func<issue, bool>>>();              filers.add(i => i.issispending == showpendingtasks);              if (includeclosedissues == false)                 filers.add(i => i.issisclosed == false);              if (showtasks == false)                 filers.add(i => i.issisonstatusboard == true);               iqueryable<issue> issuesquery = db.items.asqueryable();              foreach (var filter in filters)                 issuesquery = issuesquery.where(filter);              issuesquery = in issuesquery                           orderby i.ississticky descending, !i.issduedate.hasvalue ascending, i.issduedate, i.issurgency                           select i;              return issuesquery.tolist(); //it serialized in case         }     } } 

service:

public class service1 : iservice1 {     public list<issue> getissues()     {         return issuesrepository.getissues();     } } 

advantages: independent on protocol; provide sessions, security, transactions.

so conclusion recommend use dataservices if need crud functionality, , common wcf services if use set of operations complex logic.


Comments

Popular posts from this blog

javascript - Enclosure Memory Copies -

php - Replacing tags in braces, even nested tags, with regex -