2009-07-23 8 views
2

Comment puis-je implémenter le "modèle de référentiel" que Rob Conery montre dans [MVC Storefront] [1] lorsque j'utilise deux codes linq différents? Ai-je besoin d'implémenter un véritable modèle de référentiel tel que discuté par Fredrik Normen au What purpose does the Repository Pattern have?? Le truc est que je veux passer certaines des fonctionnalités que LINQ fournit à partir de mon "référentiel" pour pouvoir l'utiliser plus tard, donc si ce n'est pas nécessaire, je ne veux pas implémenter un vrai modèle de dépôt comme Fredrik l'a dit.Modèle de repositionnement utilisant linq

Maintenant à mon problème. J'ai téléchargé [dblinq] [3] qui est un fournisseur de Linq pour MySql, Oracle et PostgreSQL. Dans mon projet, j'ai maintenant généré du code LINQ pour MySQL et SQL (microsoft). Le problème est qu'ils doivent tous deux générer des classes avec les mêmes noms mais avec un contenu quelque peu différent. Puis-je utiliser en quelque sorte l'implémenter avec des espaces de noms ou quelque chose de sorte que je puisse être capable de les utiliser tous les deux, comme c'est le cas avec le "modèle de dépôt"? Exemple pour une table de langue SQl

[Table(Name="dbo.Language")] 
public partial class Language : INotifyPropertyChanging, INotifyPropertyChanged 
{ 

    private static PropertyChangingEventArgs emptyChangingEventArgs = new PropertyChangingEventArgs(String.Empty); 

    private int _Id; 

    private string _Name; 

    private EntitySet<Book> _Books; 

#region Extensibility Method Definitions 
partial void OnLoaded(); 
partial void OnValidate(System.Data.Linq.ChangeAction action); 
partial void OnCreated(); 
partial void OnIdChanging(int value); 
partial void OnIdChanged(); 
partial void OnNameChanging(string value); 
partial void OnNameChanged(); 
#endregion 

    public Language() 
    { 
     this._Books = new EntitySet<Book>(new Action<Book>(this.attach_Books), new Action<Book>(this.detach_Books)); 
     OnCreated(); 
    } 

    [Column(Storage="_Id", AutoSync=AutoSync.OnInsert, DbType="Int NOT NULL IDENTITY", IsPrimaryKey=true, IsDbGenerated=true)] 
    public int Id 
    { 
     get 
     { 
      return this._Id; 
     } 
     set 
     { 
      if ((this._Id != value)) 
      { 
       this.OnIdChanging(value); 
       this.SendPropertyChanging(); 
       this._Id = value; 
       this.SendPropertyChanged("Id"); 
       this.OnIdChanged(); 
      } 
     } 
    } 

    [Column(Storage="_Name", DbType="NVarChar(100) NOT NULL", CanBeNull=false)] 
    public string Name 
    { 
     get 
     { 
      return this._Name; 
     } 
     set 
     { 
      if ((this._Name != value)) 
      { 
       this.OnNameChanging(value); 
       this.SendPropertyChanging(); 
       this._Name = value; 
       this.SendPropertyChanged("Name"); 
       this.OnNameChanged(); 
      } 
     } 
    } 

    [Association(Name="Language_Book", Storage="_Books", ThisKey="Id", OtherKey="Language")] 
    public EntitySet<Book> Books 
    { 
     get 
     { 
      return this._Books; 
     } 
     set 
     { 
      this._Books.Assign(value); 
     } 
    } 

    public event PropertyChangingEventHandler PropertyChanging; 

    public event PropertyChangedEventHandler PropertyChanged; 

    protected virtual void SendPropertyChanging() 
    { 
     if ((this.PropertyChanging != null)) 
     { 
      this.PropertyChanging(this, emptyChangingEventArgs); 
     } 
    } 

    protected virtual void SendPropertyChanged(String propertyName) 
    { 
     if ((this.PropertyChanged != null)) 
     { 
      this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); 
     } 
    } 

    private void attach_Books(Book entity) 
    { 
     this.SendPropertyChanging(); 
     entity.Language1 = this; 
    } 

    private void detach_Books(Book entity) 
    { 
     this.SendPropertyChanging(); 
     entity.Language1 = null; 
    } 
} 

MySQL

[Table(Name = "asp.Language")] 
public partial class Language : INotifyPropertyChanged 
{ 
    #region INotifyPropertyChanged handling 

    public event PropertyChangedEventHandler PropertyChanged; 

    protected virtual void OnPropertyChanged(string propertyName) 
    { 
     if (PropertyChanged != null) 
     { 
      PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); 
     } 
    } 

    #endregion 

    #region int ID 

    private int _id; 
    [DebuggerNonUserCode] 
    [Column(Storage = "_id", Name = "Id", DbType = "int", IsPrimaryKey = true, IsDbGenerated = true, CanBeNull = false)] 
    public int ID 
    { 
     get 
     { 
      return _id; 
     } 
     set 
     { 
      if (value != _id) 
      { 
       _id = value; 
       OnPropertyChanged("ID"); 
      } 
     } 
    } 

    #endregion 

    #region string Name 

    private string _name; 
    [DebuggerNonUserCode] 
    [Column(Storage = "_name", Name = "Name", DbType = "varchar(100)", CanBeNull = false)] 
    public string Name 
    { 
     get 
     { 
      return _name; 
     } 
     set 
     { 
      if (value != _name) 
      { 
       _name = value; 
       OnPropertyChanged("Name"); 
      } 
     } 
    } 

    #endregion 

    #region Children 

    private EntitySet<Book> _book; 
    [Association(Storage = "_book", OtherKey = "Language", ThisKey = "ID", Name = "Book_ibfk_1")] 
    [DebuggerNonUserCode] 
    public EntitySet<Book> Book 
    { 
     get 
     { 
      return _book; 
     } 
     set 
     { 
      _book = value; 
     } 
    } 


    #endregion 

    #region Attachement handlers 

    private void Book_Attach(Book entity) 
    { 
     entity.LanguageLanguage = this; 
    } 

    private void Book_Detach(Book entity) 
    { 
     entity.LanguageLanguage = null; 
    } 


    #endregion 

    #region ctor 

    public Language() 
    { 
     _book = new EntitySet<Book>(Book_Attach, Book_Detach); 
    } 

    #endregion 

} 

Répondre

1

Idéalement, vous ne créeriez chaque classe qu'une seule fois et les différences de base de données devraient être prises en charge par l'ORM (c'est ainsi que NHibernate et Subsonic fonctionnent).

Si vous avez vraiment besoin de classes différentes pour chaque base de données, alors oui, vous pouvez avoir des classes avec le même nom tant qu'elles sont dans différents espaces de noms. Si vous écrivez le code pour les classes vous-même est très facile:

// C# sample 
namespace MyCompany.MyApp.Entities.Oracle 
{ 
    public class MyClass 
    { 
    // ... 
    } 
} 

namespace MyCompany.MyApp.Entities.SqlServer 
{ 
    public class MyClass 
    { 
    // ... 
    } 
} 

Si les classes sont générées automatiquement, vous devriez vérifier dans l'outil de génération de code comment spécifier les espaces de noms. Par exemple, avec le concepteur LINQ to SQL, vous pouvez spécifier l'espace de noms dans les propriétés de table/classe ou en éditant vous-même le fichier DBML.

1

C'est un peu hors-sujet, mais il pourrait aider. Si vous utilisez Linq, les dépôts, MySql et MS Sql, et les conseils de Rob Connery, vous pouvez aussi utiliser SubSonic 3 et vous rendre la vie un peu plus facile.

Voici une démo de 5 minutes: http://subsonicproject.com/docs/Simple_Repo_5_Minute_Demo

+0

Merci pour la réponse. SubSonic semble en effet prometteur. Mais je veux en savoir plus sur .net avant de commencer à utiliser quelque chose comme ça (je viens d'essayer .net pour une semaine maintenant). – unkownt

0

Je suis dans la même situation que vous, je suis LINQ to SQL, mais à l'avenir je veux essayer Entity Framework, et je le ferai . Pour ce que j'ai vu, la solution de cela est l'injection de dépendance d'utilisation et un conteneur ioc (si vous ne l'utilisez pas, jetez un oeil, peut sembler difficile mais est très facile et intéressant).

La plupart des exemples de cela, crée une interface pour chaque référentiel, puis avec le fichier de configuration ioc, vous pouvez choisir ce que vous voulez utiliser.

Par exemple, vous avez un ICustomersRepository, c'est-ce que vous pouvez utiliser dans vos contrôleurs, et un SQLCustomersRepository et un EntityCustomersRepository, que vous pouvez échanger uniquement modifier le fichier de configuration. Comme vous l'avez dit le problème est les entités avec le même nom ... la solution est d'utiliser le même modèle pour les entités, de créer une interface pour chaque entité et d'utiliser le conteneur ioc. Je sais que c'est tedius, ce que je ferais est de créer un template T4 qui créerait les interfaces pour chaque entité automatiquement et remplacerait ensuite les templates T4, qui utilisent LinqToSQL et le framework Intey pour l'implémenter ... oui c'est beaucoup de travail.

Pour une introduction de T4 un coup d'oeil à cette vidéo, http://msdn.microsoft.com/en-us/vstudio/cc308634.aspx

0

je suggère un espace de noms d'entité pour votre BO, comme MyCompany.MyApp.Entities.

Vous pouvez ensuite modifier la propriété Entity Namespace de chaque DBML pour générer vos entités dans ce domaine. Si vous utilisez plus d'un DBML pour les mêmes types, vous devez disposer d'un espace de nom distinct pour chaque DBML, tel que MyCompany.MyApp.Entities.Si vous avez besoin de classes pour plus d'un type de base de données/accès aux données, je vous suggère de créer des classes de base abstraites que vos entités peuvent concrétiser, et un référentiel abstrait pour accéder aux données. Dans ma propre expérience, j'ai récemment créé un LinqToSqlRepostory abstrait, puis l'ai étendu pour mes principaux objets de gestion.

Questions connexes