2009-03-12 18 views
0

Linq to SQL veritabanı modelinde oluşturulan kısmi bir Cart sınıfını genişletiyorum (burada doğru sözcük olup olmadığından emin değilim).Yapıcıdaki iş mantığı - C#/Linq'den Sql'ye

İş mantığı, müşteri başına yalnızca bir Cart olabileceğidir. Bir müşterinin bir arabası yoksa, oluşturulmalıdır; Bir müşterinin arabası varsa, iade edilmelidir.

İşte yapıyorum:

public partial class Cart 
{ 
    //the rest of the Cart class is in the .dbml file created by L2S 
    public Cart(int userId) 
    { 
     Cart c = GetCurrentCart(userId); 
     this.CartId = c.CartId ; 
     this.UserId = c.UserId; 
    } 

    public Cart GetCurrentCart(int userId) 
    { 
     Cart currentCart = new Cart(); 

     // if cart exists - get it from DB 
     //if not - create it, save in DB, and get if right out 
     //all of this is done with Linq to SQL 

     return currentCart; 
    } 
} 

sadece doğru görünmüyor yapıcı bir yöntemin çağrılması. İş mantığını doğru şekilde uyguluyor muyum?

cevap

8

"Cart" sınıfının neden bu kadar akıllı olduğunu sorgularım. Domain Driven Design terimlerinde, Kullanıcı Sepeti "sahibi" gibi görünüyor. Öyleyse neden olmasın:

var user = // Load a user 
var cart = user.Cart; 

Bu durumda Cart alıcınız arabayı rahatça yükleyebilir/başlatır.

+0

iyi nokta. Kodumda yanlış bir şey var mı, bunun yanında DDD yolu yazılmıyor mu? –

+0

Sanırım yayınladığınız kod sayesinde, yapıcıdaki veritabanı aramalarının doğru şey olup olmadığı konusunda kendinizden emin değildiniz. En kötü suç olmasa da, biraz kod kokusu. Bence bu içgüdülerin iyi olduğu bir durum. –

+0

Kod kokusu ile demek istediğim, muhtemelen yapmaktan kaçınmak isteyeceğiniz bir şey (içgüdülerinizin önerdiği gibi). Yani alternatif bir tasarım arayışı (sorunlu alan için daha mantıklı olan, daha teknik açıdan temiz olanı) iyi bir fikirdir. –

5

Paul Stovell ile aynı fikirdeyim, kullanıcının arabanın sahibi olması gerektiği gibi görünüyor. Ama herhangi bir oranda, kurucunuzun çağrıldığı andan itibaren yeni bir Cart örneğiniz var. C# kurucu tarafından döndürülen referansı değiştirmenize izin vermez, bu nedenle kurucuyu kullanarak statik bir fabrika yöntemini çağırması gereken Cart sınıfının istemcileri yerine (Linq'den SQL'e deneyimim yok, bu yüzden işe yaramayabilir direkt olarak).

GetCurrentCart yönteminiz neredeyse budur; sadece onu statik olarak işaretlemelisiniz. Ek olarak, Cart kurucusunu yeni bir Cart oluşturmaktan ve müşterinin GetCurrentCart'ı kullanmak zorunda kalması için özel hale getirmekten sorumlu olmalısınız. Bir uygulama şöyle görünebilir:

public partial class Cart 
{ 
     // Make a new cart 
     private Cart(int userId, int cartId) 
     { 
      this.CartId = userId; 
      this.UserId = cartId; 
     } 

     private static Dictionary<int, Cart> CurrentCarts = new Dictionary<int, Cart>(); 

     public static Cart GetCurrentCart(int userId) 
     { 
      // TODO: Use a proper caching mechanism that will at least 
      //  remove old carts from the dictionary. 
      Cart cart; 
      if (CurrentCarts.TryGetValue(userId, out cart)) 
      { 
       return cart; 
      } 

      cart = /* try get cart from DB */; 
      if (cart == null) 
      { 
       // Make a new cart 
       cart = new Cart(userId, GenerateCartId()); 
      } 

      CurrentCarts[userId] = cart; 

      return cart; 
     } 
} 
+0

neden sözlük? Kullanıcı sadece bir tane –

+0

sepetine sahip olabilir. Sözlük için anahtarın userId olduğunu unutmayın, bu nedenle kullanıcı başına yalnızca bir araba olabilir. Sözlük, GetCurrentCart'ın aynı userId ile önceki çağrı için döndürdüğü Cart'ın aynı örneğini döndürmesine izin verir. – Dave