C# 构造函数中的业务逻辑-C/Linq到Sql

C# 构造函数中的业务逻辑-C/Linq到Sql,c#,linq-to-sql,.net-3.5,class-design,C#,Linq To Sql,.net 3.5,Class Design,我不确定它是否是在LINQtoSQL数据库模型中生成的部分Cart类的正确单词 业务逻辑是每个客户只能有一个购物车。如果客户没有购物车,则应创建购物车;如果客户有购物车,则应将其退回 以下是我正在做的: public partial class Cart { //the rest of the Cart class is in the .dbml file created by L2S public Cart(int userId) { Cart c =

我不确定它是否是在LINQtoSQL数据库模型中生成的部分Cart类的正确单词

业务逻辑是每个客户只能有一个购物车。如果客户没有购物车,则应创建购物车;如果客户有购物车,则应将其退回

以下是我正在做的:

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;
    }
}

从构造函数调用方法似乎并不正确。我是否以正确的方式实施了业务逻辑?

我会质疑Cart类为何如此智能。在领域驱动的设计术语中,听起来像是用户拥有购物车。那么,为什么不这样做呢:

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

在这种情况下,您的购物车获取者可以延迟加载/初始化购物车

我同意Paul Stovell的观点,听起来用户应该拥有购物车。但无论如何,在调用构造函数时,您已经有了一个新的Cart实例。C不允许您更改构造函数返回的引用,因此与其使用构造函数的Cart类的客户机,还不如调用静态工厂方法,因为我没有Linq to SQL的经验,所以这可能无法直接工作

您的GetCurrentCart方法几乎就是这样;您只需要将其标记为静态。此外,您应该让购物车构造函数只负责创建一个新购物车,并将其设置为私有,以便强制客户机使用GetCurrentCart。实现可能如下所示:

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;
        }
}

说得好。我的代码除了没有以DDD方式编写之外还有什么问题吗?我认为有趣的是,对于您发布的代码,您自己不确定在构造函数中查找数据库是否正确。虽然这不是最严重的犯罪,但有点像是一股代码的味道。我认为这是一个你的直觉很好的例子。所谓代码气味,我的意思是,这是你可能想要避免做的事情,正如你的直觉所暗示的那样。因此,寻找一种技术上更干净、对问题领域更有意义的替代设计是一个好主意。为什么?用户只能有一个购物车注意,字典的键是userId,因此每个用户只能有一个购物车。字典允许GetCurrentCart使用相同的用户ID返回与上次调用完全相同的Cart实例。