5

目标

计算List<T>C# 中每个产品的最终价格。

问题

我需要计算price * quantity一个简单的产品并将结果返回给视图。

看看这个语法:

var productPrice = productsPrices.Find(x => x.productId == 1); 
productPrice.finalProductPrice = 
    (productPrice.promotionalProductPrice != 0 ? 
        productPrice.promotionalProductPrice : 
        productPrice.originalProductPrice) 
    * sessionProducts.Find(x => x.id == 1).quantity;

就在上面传递的代码片段之前,有一个存储产品 id 的字符串,请参见:

string ids = string.Join(", ", sessionProducts.Select(x => x.id));

而且我认为我需要它为列表finalProductPrice中的每个产品设置一个值productsPrices,但我不知道如何执行此操作。

我对这个问题的看法:

我曾认为我可以使用这样的东西:

productsPrices.Find(x => x.productId == productsPrices.Contains(ids))
    .finalProductPrice = 
    (productsPrices.Find(x => productsPrices.Contains(ids))
        .promotionalProductPrice != 0 ?
    productsPrices.Find(x => productsPrices.Contains(ids))
        .promotionalProductPrice : 
    productsPrices.Find(x => productsPrices.Contains(ids))
        .originalProductPrice) *
    sessionProducts.Find(x => x.id == 1).quantity;

但是,当然,没有成功 -.Contains()不适用于字符串。

真正的问题

如何finalProductPrice为我的列表中的每个产品定义权利productsPrices?如何将每个 id 传递string ids [...]给 to x.productId == something

欢迎提示(例如,不要使用.Find().Select()而是使用!)

聚焦代码

按照我ActionResult的发送所有必要信息到我的视图:

比较.cs

public ActionResult Compare()
{
    List<getMarkets_Result> markets = Markets.Build();

    SessionStore sessionStore = new SessionStore();
    List<getSpecificProductToShoppingList_Result> sessionProducts = 
        sessionStore.Get("ProductsSummary", "generic");

    string ids = string.Join(", ", sessionProducts.Select(x => x.id));
    List<getProductsPrices_Result> productsPrices = Products.PricesList(ids);

    ListComparisonViewModel listComparisonViewModel = 
       new ListComparisonViewModel
    {
        Markets = markets,
        SessionProducts = sessionStore.Get("ProductsSummary", "generic"),
        ProductsPrices = productsPrices
    };

    return View(listComparisonViewModel);
}

如有必要,我的productsPrice清单的上下文:

public partial class getProductsPrices_Result
{
    public decimal originalProductPrice { get; set; }
    public decimal promotionalProductPrice { get; set; }
    public decimal finalProductPrice { get; set; }
    public string productName { get; set; }
    public string marketName { get; set; }
    public int productId { get; set; }
    public int marketId { get; set; }
}

我制作了一个名为Products(.cs)的模型来执行产品背后的逻辑。该模型具有的第一个(也是唯一一个)方法是CalculateFinalPrice()

public decimal CalculateProductPriceByQuantity(decimal price, int quantity)
{
    return price * quantity;
}
4

4 回答 4

1

我认为您应该更简洁地创建一个模型来表示您的数据,从而使您的业务问题更容易解决。换句话说,让代码工作来解决你的解决方案。

首先,产品不应该知道数量。假设这就像一辆购物车,产品应该只知道它自己。所以实现finalProductPrice应该容易得多:

public decimal finalProductPrice 
{
    get 
    {
        return (promotionalProductPrice != 0 ? 
            promotionalProductPrice : 
            originalProductPrice);
    }
}

使用您的产品时,创建一个类并将它们包含在其中以计算质量和总价:

public class ProductCollection
{
    public IEnumerable<getProductsPrices_Result> Products { get; set; }
    public int Quantity { get { return Products.Count; } }
    public decimal TotalPrice 
    {
        get
        {
            return Products.Sum(p => p.finalProductPrice );
        }
    }
    public ProductCollection(IEnumerable<getProductsPrices_Result> products)
    {
        this.Products = products;
    }
}

现在您的视图模型看起来像这样:

ListComparisonViewModel
{
    Markets = markets,
    Products = new ProductCollection(sessionStore.Get("ProductsSummary", "generic"))
};

我想在这里做的一个重要说明是,这有助于减少您的会话访问表面积。会话可以“被任何人访问”,因此可能会变得混乱并导致很多问题。在几乎所有情况下,会话 cookie 罐中的手越少越好。(更少的键以及更少的类类型和实例)

于 2013-08-05T20:32:40.417 回答
0

你这里有很多问题。首先,您的属性应该是 PascalCase,而不是 camelCase。其次,你的班级名字不好。getProductsPrices_Result不应该以动词为前缀,并且应该是不带下划线的 PascalCase。

除此之外,您还有很多冗余代码。FinalProductPrice听起来不像是一个Product类型的合适属性。

要回答有关获取与 ID 集合匹配的产品集合的问题,您可以使用 LINQ:

string[] ids = ...;
List<Product> products = ...;

List<Product> matchingProducts = 
    products.Where(p => ids.Any(i => i == p.Id)).ToList();
于 2013-08-05T20:16:29.583 回答
0

问题有点模糊,但看起来您可能正在寻找类似以下的内容

var res = (from p in products
           from s in sessionproducts
           where p.id == s.id
           select new Product() { id = p.id, finalprice = s.qty * (p.promoprice > 0 ? p.promoprice : p.price) })
           .ToList();
于 2013-08-05T20:17:36.063 回答
0
  • 我会仔细检查你的课程设计。
  • 我会让promotionPrice 可以为空,如果您需要price = 0 进行促销怎么办?
  • 考虑将此作为在会话中收集产品引用的扩展方法。

用我手头的东西:

foreach(var product in sessionProducts){        
    var productPrice == productPrices.FirstOrDefault(p=>p.ProductId == product.id);
    var price = 0;
    if (productPrice != null)
       price = productPrice.promotionalPrice == 0 ? productPrice.originalPrice : productPrice.promotionalPrice;

    product.finalPrice = product.Qty * price;
}
于 2013-08-05T20:23:10.493 回答