2009-05-31 3 views
1

Je construis cette application la nuit après le travail et j'ai eu du mal avec ce problème de conception pendant une semaine ou deux maintenant.Problème avec la création de référentiel dans les entités C# et ADO.NET

Je crée un programme qui a 44 types d'entrées différents et nécessite la possibilité de créer un type personnalisé. Étant donné que les utilisateurs peuvent modifier les champs d'un type particulier d'entrée et/ou définir les leurs, ma première approche de génération d'une classe Entity pour chaque type d'entrée ne semble pas possible. Si les utilisateurs modifient l'un des champs ou leur version du schéma (sous réserve de validation, bien sûr) alors mes classes ne refléteraient pas vraiment cela.

Même si les utilisateurs n'ont pas pu modifier les champs, je souhaite m'assurer que les modifications du schéma de données ne créent pas de problèmes pour les données actuelles.

Afin de construire un schéma capable de tout cela, je l'ai fait ce qui suit:

DTYPE

  • id
  • datatype

champ

  • id fieldName

  • fieldDataType (liée par la clé étrangère à DTYPE)

dataStore

    id
    DataText
    datastring
    dataDate
    dataDouble
    dataInt
    fieldID (lié par la clé étrangère au champ)
    ENTRYID (lié par la clé étrangère au champ id des entrées)

types ol> id int

    typeName
    champs

entrées

    id
    typeid (liés par clé étrangère id de types)

Eh bien, le schéma est très dénormaliser mais difficile à travailler avec ASP.NET MVC.

Ma deuxième fissure à elle consistait à faire une classe avec des propriétés typées pour stocker l'entrée selon le type de données se trouvait.

classe personnalisé pour le niveau de domaine entrée public class { publique Liste datalist = new List();

public entry(int id) 
    { 
     kleraDataContext s = new kleraDataContext(); 
     var dataSet = s.dataStores.Where(c => c.citationID == id); 
     foreach (dataStore y in dataSet) 
     { 
      dataBlob tempd = new dataBlob(); 

      //We get the data type id 
      var temp = s.fields.Where(c => c.id == y.fieldID).First(); 

      //Get the fieldname and store the data type id for later 
      tempd.fieldname = temp.fieldName; 
      tempd.dataType = temp.dtype.dataType; 

      switch (tempd.dataType) 
      { 
       case "String": 
        tempd.dString = y.dataString; 
        break; 
       case "Text": 
        tempd.dString = y.dataText; 
        break; 
       default: 
        //Nothing 
        break; 
      } 

      this.dataList.Add(tempd); 
     } 
    } 
} 

    public class dataBlob 
    { 
     private string _dString; 
     private DateTime _dDate; 
     private int _dInt; 
     private double _dDouble; 
     private object _data; 
     private string _fieldname; 
     private string _dataType; 

     public string dataType 
     { 
      get 
      { 
       return _dataType; 
      } 
      set 
      { 
       _dataType = value; 
      } 

     } 

     public object data 
     { 
      get 
      { 
       return _data; 
      } 
     } 

     public string dString 
     { 
      get 
      { 
       return _dString; 
      } 
      set 
      { 
       _dString = value; 
       _data = value; 
      } 

     } 

     public string fieldname 
     { 
      get 
      { 
       return _fieldname; 
      } 
      set 
      { 
       _fieldname = value; 
      } 
     } 

     public DateTime dDate 
     { 
      get 
      { 
       return _dDate; 
      } 
      set 
      { 
       _dDate = value; 
       _data = value; 
      } 

     } 

     public double dDouble 
     { 
      get 
      { 
       return _dDouble; 

      } 
      set 
      { 
       _dDouble = value; 
       _data = value; 
      } 

     } 

     public int dInt 
     { 
      get 
      { 
       return _dInt; 

      } 
      set 
      { 
       _dInt = value; 
       _data = value; 
      } 

     } 
    } 
} 

Notez plusieurs problèmes avec ceci.

  1. Je vais avoir du mal à obtenir une propriété suffisamment générique pour stocker les données, peu importe quel type champ, il est dans la structure physique. Idéalement, l'accesseur de données récupérerait tout ce que le type de données était.
  2. Je n'ai toujours pas assez bon moyen de fournir des vues de ASP.NET MVC avec un modèle assez cohérent pour que le code de présentation ne doit pas faire l'analyse syntaxique. Idéalement, la vue obtiendrait juste un objet avec une liste de champs et avec leurs données correspondantes.
  3. Relatif à # 2, je n'arrive pas à trouver un moyen approprié de persister des changements. Ecrire une requête et la faire retourner les champs à la vue pourrait être fait. Comme chaque champ n'est pas un accesseur fortement typé, je ne suis pas sûr de savoir comment conserver le changement de la vue au modèle. Naïvement, j'ai pensé à insérer une clé dans une plage cachée et à utiliser un objet Dictionary dans le contrôleur pour mapper les modifications/créations.

Pensées?

Ron

+0

Je n'ai pas beaucoup de temps, c'est pourquoi je n'ai pas assez analysé votre question, mais je voulais dire que dans une situation extrême, vous pouvez utiliser C# de manière hyper-dynamique en construisant un assemblage temporaire. L'ai fait avec succès. –

Répondre

1

Bien que je ne suis pas exactement sûr de votre but ultime, je peux avoir une option pour vous. Vous avez besoin d'une «entité» hautement dynamique qui permettra à vos utilisateurs de créer leurs propres structures de données. Les langages impératifs comme C# ne se prêtent pas bien à une telle chose ... et même avec un langage dynamique, je pense que vous rencontrerez probablement des difficultés. Cependant, XML est un excellent moyen de représenter les structures de données dynamiques de manière ad-hoc et créative.

Si vous utilisez SQL Server, je vous recommande de créer un type simple, comme illustré ci-dessous, et le stocker dans une table qui utilise le type de données « xml » pour l'une des colonnes:

public class DynamicEntity 
{ 
    public int ID { get; set; } 
    public string TypeName { get; set; } 
    public XDocument DynamicContent { get; set; } 
} 

l'entité ci-dessus pourrait être stockée dans le tableau suivant:

CREATE TABLE DynamicEntity 
(
    ID int IDENTITY(1,1) NOT NULL, 
    NAME varchar(50) NOT NULL, 
    DynamicContent xml NULL 
) 

Compte tenu des capacités XML de SQL Server, vous serez toujours en mesure d'interroger les données dans cette colonne xml. Non seulement cela, si vous voulez que les structures personnalisées de vos utilisateurs soient validées par rapport à un schéma, vous pouvez aussi mettre ce schéma dans la base de données et 'taper' votre colonne xml contre ce schéma. L'utilisation d'une colonne XML dans SQL Server s'accompagne de mises en garde, mais il peut s'agir d'une solution simple à votre problème complexe.

Questions connexes