Domanda

Al momento sto ricercando come porta il Data Access Layer di .NET 4.0 esistente MVC 3 applicazione web verso un quadro entità. Ci sono molte ragioni, ma quello principale è a causa di migliaia di stored procedure, aggiungendo solo 1 campo per un risultato tavolo in 30 - 50 sproc modifiche !!

Stiamo utilizzando MS SQL Server 2008 R2 e, idealmente, vorremmo utilizzare NHibernate e Fluent per la mappatura.

Ho semplificato il problema Im che ha in un semplice esempio:

Immaginate i seguenti 2 tabelle:

'Prodotti' Tabella

ID (INT)
DefaultName (NVARCHAR(128))

'I nomi del prodotto' Tabella

ProductID (INT)
Name (NVARCHAR(128))
Culture (VARCHAR(10))

La tabella Prodotti contiene un elenco di prodotti, ciascuno di loro avrà un default, inglese, nome. La tabella I nomi di prodotto conterrà l'ID del prodotto e molte traduzioni.

Al momento, utilizzando le stored procedure, abbiamo la seguente:

SELECT Products.ID,
       ISNULL(ProductNames.Name, Products.DefaultName) AS Name
FROM Products
LEFT JOIN ProductNames ON ProductNames.ProductID = Products.ID AND ProductNames.Culture = @Culture;

Nota: @Culture è passato nella procedura

Ciò assicura sempre un unico prodotto con un nome o di default localizzato viene restituita (inglese) nome.

La mia domanda è: Questo è possibile fare a livello di mappatura di Fluent NHibernate? Ho cercato per giorni su 'Come aderire su 2 colonne', ma cant trovare una soluzione che funziona. Sembrerebbe strano se ciò non è possibile in un tale quadro maturare?

Per fare un esempio di quello che ho avuto modo di sperimentare con:

public class ProductMap : ClassMap<Product> {
  public ProductMap() {
    Id(p => p.Id);

    Join("ProductNames", pn => {
      pn.Optional()
        .KeyColumn("ProductID")
        .Map(p => p.Name);
    });
  }
}

Tuttavia, il risultato è la seguente eccezione:

More than one row with the given identifier was found: 109, for class: Product

Questo è perché prodotto 109 ha 5 definizioni e quindi tutte 5 non può essere associata a una singola stringa.

Sono riuscito a utilizzare il 'hasMany <>' il metodo per mappare tutti traduzioni in un elenco all'interno di un prodotto. Tuttavia, questo non è quello che mi serve.

È stato utile?

Soluzione

Se il nome è di sola lettura, allora

public class ProductMap : ClassMap<Product> {
    public ProductMap() {
        Id(p => p.Id);

        Map(p => p.Name).Formula("Select ISNULL(pn.Name, DefaultName) FROM ProductNames pn WHERE pn.ProductID = ID AND pn.Culture = '" + GetCUltureFromSomewhere() + "'");
    }
}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top