Question

J'ai une classe de base abstraite pour les propriétés de vérification. Par souci de concision dire qu'il a une propriété

Public MustInherit Class AbstractAuditableEntity  
  ...  
  Public Property CreatedTime() As DateTimeOffset 
  ...
End Class  

Et puis mes objets de domaine auditables héritent de cette classe

Public Class Source  
  Inherits AbstractAuditableEntity  
  ...        
  Public Property SourceId() As String  
  ...
End Class  

J'ai le DDL tableau ci-dessous à laquelle je veux carte mon objet de domaine « Source ». Essentiellement, la relation entre chaque (en béton) objet de domaine et la table est 1-1, chaque table ayant la colonne de vérification requise.

CREATE TABLE Source  
(  
   SourceID VARCHAR(10) NOT NULL,   
   CreatedTime   DATETIMEOFFSET(3) NOT NULL,  
   CONSTRAINT PK_Source PRIMARY KEY (SourceID))  
GO

L'utilisation d'un mappage externe fichier ma première tentative de cartographier la classe à la table serait bêtement être:

<?xml version="1.0" encoding="utf-8"?>
<Database Name="" xmlns="http://schemas.microsoft.com/linqtosql/mapping/2007">
  <Table Name="Source" Member="Sources">
    <Type Name ="Source">
      <Column Name="SourceID" Member="SourceID" IsPrimaryKey="true" CanBeNull="false"/>
      <Column Name="CreatedTime" Member="CreatedTime" />      
    </Type>
  </Table>
</Database>

Cependant, cela génère l'exception suivante:

La colonne ou association « CreatedTime » dans le mappage avaient pas membre correspondant dans le type « Source ». membres de mappage de type ci-dessus ne sont pas pris en charge racine.

Dans le cadre de ma couche de persistance Je ne suis pas en train de représenter une hiérarchie d'héritage en tant que telle, mais dans le cadre de ma demande, j'utilise simplement une classe de base aux propriétés fournies requises par tous mes objets de domaine. Avec beaucoup de jongler avec mon fichier de mappage (y compris liant les colonnes d'audit du type base de AbstractAuditableEntity) et autour de la lecture, je suis incapable de réaliser ce que je perçois comme une tâche ORM straighforward.

Toutes les pensées ou suggestions seront les bienvenues! Merci

Était-ce utile?

La solution

Kelly a montré un grand échantillon de la façon de le faire - mais vous avez essentiellement frappé l'une des limites de LINQ to SQL

.

Il fonctionne très bien si vous carte de table de base de données plus ou moins 1: 1 à vos objets de domaine. Mais il est faible et provoque beaucoup de travail supplémentaire une fois que ce ne soit plus le cas.

Dans ce cas, dès que vous avez l'héritage d'objets de domaine et d'autres choses qui doivent être mis en correspondance avec des tables de base de données, vous êtes le meilleur pari serait de vérifier ADO.NET Entity Framework à la place. L'EF est spécifiquement conçu pour gérer ces choses - si vous pensez jamais « Je dois carte mes objets ...... » alors vous devriez penser EF! : -)

Certes, l'EF actuelle navigation dans .NET 3.5 SP1 a ses verrues et contrariétés, mais l'EF 4 qui fait partie de l'onde .NET 4.0 (qui devrait expédier avant la fin de l'année 2009), devrait résoudre un grand beaucoup de ces verrues!

Consultez la page

Autres conseils

Je devine que vous essayez d'imiter les champs d'audit comme Ruby on Rails updated_on, created_on. Si oui, voici comment j'accompli quelque chose de similaire en utilisant ce post comme point de départ http://weblogs.asp.net/stevesheldon/archive/2008/02/23/a-method-to-handle-audit-fields-using-linq-to-sql.aspx

Je mis en place une interface dans l'espace de noms de modèles comme ceci:

public interface IAuditable
{
    DateTime CreatedOn { get; set; }
    string CreatedBy { get; set; }
    DateTime? ChangedOn { get; set; }
    string ChangedBy { get; set; }
}

Et puis étendu les classes partielles des entités de données qui ont ces domaines:

public partial class DataModelIWantToAudit : IAuditable
{
}

Et puis sur la SubmitChanges l'emportait sur DataContext pour vérifier la mise en œuvre de l'interface avec la magie de Linq OfType<>:

public override void SubmitChanges(ConflictMode failureMode)
{         
    //Updates
    foreach (var updatedModel in GetChangeSet().Updates.OfType<IAuditable>())
    {
        updatedModel.ChangedOn = DateTime.Now;
        updatedModel.ChangedBy = Membership.GetUser().UserName;
    }

    //Inserts
    foreach (var insertedModel in GetChangeSet().Inserts.OfType<IAuditable>())
    {
        insertedModel.CreatedOn = DateTime.Now;
        insertedModel.CreatedBy = Membership.GetUser().UserName;
    }

    base.SubmitChanges(failureMode);
}

L'espoir qui aide! -Kelly

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top