2010-04-10 14 views
1

J'ai un schéma de base de données existant et souhaite remplacer le code d'accès aux données personnalisé par Fluent.NHibernate. Le schéma de base de données ne peut pas être modifié puisqu'il existe déjà dans un produit d'expédition. Et il est préférable que les objets de domaine ne changent pas ou ne changent que de manière minimale.Mappage FluentNHibernate des clés étrangères composites

J'ai cartographie du mal à une construction de schéma inhabituel illustré par la structure de tableau suivant:

CREATE TABLE [Container] (
    [ContainerId] [uniqueidentifier] NOT NULL, 
    CONSTRAINT [PK_Container] PRIMARY KEY (
    [ContainerId] ASC 
) 
) 

CREATE TABLE [Item] (
    [ItemId]  [uniqueidentifier] NOT NULL, 
    [ContainerId] [uniqueidentifier] NOT NULL, 
    CONSTRAINT [PK_Item] PRIMARY KEY (
    [ContainerId] ASC, 
    [ItemId] ASC 
) 
) 

CREATE TABLE [Property] (
    [ContainerId] [uniqueidentifier] NOT NULL, 
    [PropertyId] [uniqueidentifier] NOT NULL, 
    CONSTRAINT [PK_Property] PRIMARY KEY (
    [ContainerId] ASC, 
    [PropertyId] ASC 
) 
) 

CREATE TABLE [Item_Property] (
    [ContainerId] [uniqueidentifier] NOT NULL, 
    [ItemId]  [uniqueidentifier] NOT NULL, 
    [PropertyId] [uniqueidentifier] NOT NULL, 
    CONSTRAINT [PK_Item_Property] PRIMARY KEY (
    [ContainerId] ASC, 
    [ItemId]  ASC, 
    [PropertyId] ASC 
) 
) 

CREATE TABLE [Container_Property] (
    [ContainerId] [uniqueidentifier] NOT NULL, 
    [PropertyId] [uniqueidentifier] NOT NULL, 
    CONSTRAINT [PK_Container_Property] PRIMARY KEY (
    [ContainerId] ASC, 
    [PropertyId] ASC 
) 
) 

Le modèle de domaine existant a la structure de classe suivante:

alt text http://yuml.me/4e2bcb95

La classe de propriété contient les autres membres représentant le nom et la valeur de la propriété. Les classes ContainerProperty et ItemProperty n'ont aucun membre supplémentaire. Ils n'existent que pour identifier le propriétaire de la propriété. Les classes Container et Item ont des méthodes qui retournent des collections de ContainerProperty et ItemProperty respectivement. En outre, la classe Container a une méthode qui retourne une collection de tous les objets Property dans le graphique d'objet. Ma meilleure supposition est que c'était une méthode de commodité ou une méthode héritée qui n'a jamais été enlevée.

La logique métier fonctionne principalement avec Item (en tant que racine agrégée) et ne fonctionne qu'avec un conteneur lors de l'ajout ou de la suppression d'éléments.

J'ai essayé plusieurs techniques pour mapper ceci mais aucune ne fonctionne donc je ne les inclurai pas ici à moins que quelqu'un ne les demande. Comment allez-vous cartographier cela?

Répondre

1

Mapping devrait ressembler cette façon:

public sealed class CategoryMap : ClassMap<Category> 
{ 
    public CategoryMap() 
    { 
     Table("Categories"); 
     CompositeId() 
      .KeyProperty(c => c.ItemId, "ItemId") 
      .KeyProperty(c => c.CategoryId, "CategoryId"); 
    } 
} 

Note:

  1. Catégorie classe d'entité devrait remplacer equals() et GetHashCode() méthodes
  2. Toutes les propriétés et méthodes doivent être virtuel/écrasé!

-

public class Category 
{ 
    public virtual int ItemId { get; set; } 
    public virtual int CategoryId { get; set; } 

    public override bool Equals(object obj) 
    { 
     if (ReferenceEquals(null, obj)) return false; 
     if (ReferenceEquals(this, obj)) return true; 
     if (obj.GetType() != typeof (Category)) return false; 
     return Equals((Category) obj); 
    } 

    public virtual bool Equals(Category other) 
    { 
     if (ReferenceEquals(null, other)) return false; 
     if (ReferenceEquals(this, other)) return true; 
     return other.ItemId == ItemId && other.CategoryId == CategoryId; 
    } 

    public override int GetHashCode() 
    { 
     unchecked 
     { 
      return (ItemId*397)^CategoryId; 
     } 
    } 
} 
Questions connexes