Frage

Inspiriert vom DDD -Hype, entworfen ich meine Klassen, als ich so tat, als gäbe es überhaupt keine Datenbank. Und dann verwendete NHiberNate, um die Klassen auf Datenbanktabellen zuzuordnen. Ein Teil meiner Klassengrafik sieht folgendermaßen aus: Order (Hasmany)-> Produkt (hingänglicher)-> Verkäufer. Alle Bestellungen für einen bestimmten Verkäufer abrufen. Ich habe den Code:

public class Order:ActiveRecordBase<Order>
{
    [HasMany]
    public ICollection<Product> Items{get;set;}
    ...
}

public class Product: Order:ActiveRecordBase<Product>
{
    [BelongsTo]
    public Seller Seller{get; set;} 
    ...
}

public class OrderRepository:IOrderRepository
{
    public IQuerable<Order> GetOrdersBySellerId(int sellerId)
    {
        return Order.FindAll().AsQuerable.Where(x=>x.Items.Count > 0 &&
                                                   x.Items.First().Seller.SellerID == sellerId).AsQuerable();

    }
}

Nicht schön, aber es hat mit meinen Unit -Tests funktioniert. Ich war glücklich, bis wir anfingen, echte Daten in die Datenbank zu injizieren. Die Leistung ist so schlecht, dass ich mich übergeben möchte. Also habe ich eine kleine Untersuchung für meinen Repository -Code durchgeführt. Um die gewünschten Bestellungen zu finden, musste ich alle Daten aus der Bestellentabelle und alle Daten aus der Produkttabelle und einige Daten aus der Verkäufertabelle überraschen.

Also, hier kommt mein Problem. Als totaler Dummy im Datenbankbereich weiß ich nicht, wie ich meinen Repository -Code verbessern kann, obwohl ich weiß, dass er schlecht stinkt. Ich bin also versucht, meine Bestellkurs so zu ändern, dass sie einen Verweis auf die Verkäuferklasse haben, damit ich mit HQL eine Where -Klausel hinzufügt, um die Leistung zu verbessern. Die Änderung der Klassenstruktur aufgrund des Datenbankproblems scheint jedoch gegen die DDD -Prinzipien zu verstoßen.

Was ist Ihr Vorschlag, insbesondere bei der Verbesserung meines Repository -Codes? Ich habe Linq für ActiveCord und HQL ausprobiert. Aber konnte sie nicht zum Laufen bringen.

War es hilfreich?

Lösung 2

Nach viel Nachforschungen habe ich diese HQL -Erklärung erhalten

public IQuerable<Order> GetOrdersBySellerId(int sellerId)
{
     string hql = @"select  o 
                    from     Order o, Product p
                    where    p.Seller.SellerID=:sellerID
                    and      p in elements(o.Items )";

     SimpleQuery<Order> q = new SimpleQuery<Order>(hql);
     q.SetParameter("sellerID", sellerID);
            return q.Execute().AsQueryable();
}

Danke für Dies Post. Ich hatte die Idee aus Ayende's Antwort. Bitte lassen Sie mich wissen, ob dies die Leistung booten wird.

Andere Tipps

Obwohl Afaik Activerecord keine direkte Unterstützung von LinQ hat, können Sie LINQ zum NHibernate -Anbieter verwenden. Hier ist eine Probe. Am Ende gibt es ein Beispiel für die Verwendung von traditionelleren und reifen Kriterien -API.

Update: Entschuldigung, ich habe mich geirrt. Es scheint, dass Sie Ihre Entitäten von erben müssen ActiveRecordLinqBase<T>, und bauen Sie Fragen mit ihren Queryable Eigentum.

Es sollte wie aussehen wie

public IQuerable<Order> GetOrdersBySellerId(int sellerId)
{
    return Order.Queryable
               .Where(x=>x.Items.Count > 0 && x.Items.First().Seller.SellerID == sellerId)();
}

Wenn Sie sich bei einfach halten möchten ActiveRecordBase<T>, Sie können die statische Methode verwenden ActiveRecordLinq.AsQueryable<T>().

public IQuerable<Order> GetOrdersBySellerId(int sellerId)
{
    return ActiveRecordLinq.AsQueryable<Order>()
               .Where(x=>x.Items.Count > 0 && x.Items.First().Seller.SellerID == sellerId)();
}

Haben Sie es mit Ihren Suchkriterien ausprobiert? (Ich frage das, weil Afaik Sie nicht alle linq konstruiert, die an Nhibernate arbeiten)

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top