generics - Linq to SQL: Many to Many support class -


i'd have support class many many relationship.

as see double generic class define in 1 or both of entity partial classes surrounding relationship.

getting allow access other table without having mention relationship table should easy. adding or removing collection trickier. ahve add row relationship table aswell , commit or remove based on done.

could done through function passed generic class?

does class exists , if not can viably done?

you can create imanytomanyset<tentity> interface can returned many many property , have manytomanyset<tsource, tcross, tdestination> implementation query insert , delete features.

the interface may this:

public interface imanytomanyset<tentity> : ienumerable<tentity>     tentity : class {     int count { get; }     void add(tentity entity);     bool remove(tentity entity);     void addrange(ienumerable<tentity> collection); } 

and implementation might this:

public class manytomanyset<tsource, tcross, tdestination>     : imanytomanyset<tdestination>, ienumerable<tdestination>     tdestination : class     tsource : class     tcross : class {     private tsource source;     private entityset<tcross> crossset;     private func<tcross, tdestination> destinationselector;     private func<tsource, tdestination, tcross> crossfactory;      public manytomanyset(tsource source,          entityset<tcross> crossset,         func<tcross, tdestination> destinationselector,         func<tsource, tdestination, tcross> crossfactory)     {         this.source = source;         this.crossset = crossset;         this.destinationselector = destinationselector;         this.crossfactory = crossfactory;     }      public int count     {         { return this.crossset.count; }     }      public void add(tdestination entity)     {         var newentity = this.crossfactory(this.source, entity);         this.crossset.add(newentity);     }      public bool remove(tdestination entity)     {         var existingentity = (             c in this.crossset             this.destinationselector(c) == entity             select c)             .singleordefault();          if (existingentity != null)         {             return this.crossset.remove(existingentity);         }          return false;     }      public void addrange(ienumerable<tdestination> collection)     {         foreach (var entity in collection)         {             this.add(entity);         }     }      public ienumerator<tdestination> getenumerator()     {         return this.crossset.select(this.destinationselector)             .getenumerator();     }      ienumerator ienumerable.getenumerator()     {         return this.getenumerator();     } } 

you need supply couple of things in implementation:

  1. the tsource instance, points @ entity defines property.
  2. the entityset<tcross> points list of entities define cross table.
  3. a projection function allows convert tcross tdestination.
  4. a factory function allows create new tcross based on tsource , tdestination.

translating practical example (using product , order), give following property in order entity:

private imanytomanyset<product> products; public imanytomanyset<product> products {         {         if (this.products != null)         {             this.products = new manytomanyset<order, orderproduct, product>(                 this, this.orderproducts, op => op.product,                 (o, p) => new orderproduct { order = o, product = p });         }          return this.products;     } } 

and following property in product entity:

private imanytomanyset<order> orders; public imanytomanyset<order> orders {         {         if (this.orders == null)         {             this.orders = new manytomanyset<product, orderproduct, order>(                 this, this.orderproducts, op => op.order,                 (p, o) => new orderproduct { order = o, product = p });         }          return this.orders;     } } 

the imanytomanyset<t> interface in fact redundant, because can return manytomany<tsource, tcross, tdestination> directly. interface hides tsource , tcross type arguments, makes bit more readable user of property.

note implementation has same loading behavior linq sql's entityset<t>; when used, loads complete set of objects in memory. entityset<t> using where or first on collection, still loads complete collection database. need aware of that.

important difference linq sql understands entityset<t> properties within linq queries. having imanytomanyset<t> inside linq query fail miserably.

i hope helps.


Comments

Popular posts from this blog

php - What is the difference between $_SERVER['PATH_INFO'] and $_SERVER['ORIG_PATH_INFO']? -

fortran - Function return type mismatch -

queue - mq_receive: message too long -