You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

无数据库实现90个C#产品间可变更关联关系的技术问询

Got it, let's walk through how to solve this problem with your existing C# DataContracts—no database required. Here's a practical, editable solution that handles dynamic product associations and their CO2 emission (ProductPoints) impacts.

1. Extend Your DataContracts to Track Associations

First, we need to add a way to store editable association relationships between products. Since associations are between individual products, we'll extend your Product class with a dictionary to map target product numbers to their association type. We'll also define an enum to clarify association types:

// Define clear association types
public enum AssociationType
{
    Positive, // Boosts CO2 value
    Negative, // Reduces CO2 value
    Neutral   // No impact
}

[DataContract(Name = "Product", Namespace = "")]
public class Product {
    private List<ProductTypes> productTypes = new List<ProductTypes>();
    // Store associations: key = target ProductNumber, value = association type
    private Dictionary<long, AssociationType> productAssociations = new Dictionary<long, AssociationType>();

    [DataMember(Name = "ProductName", IsRequired = true, Order = 1, EmitDefaultValue = false)]
    public string ProductName { get; set; }

    [DataMember(Name = "ProductTypes", IsRequired = true, Order = 2, EmitDefaultValue = false)]
    public List<ProductTypes> ProductTypes { get { return productTypes; } set { productTypes = value; } }

    // Serializeable association storage (preserves edits between sessions)
    [DataMember(Name = "ProductAssociations", IsRequired = false, Order = 3, EmitDefaultValue = false)]
    public Dictionary<long, AssociationType> ProductAssociations 
    { 
        get { return productAssociations; } 
        set { productAssociations = value ?? new Dictionary<long, AssociationType>(); } 
    }
}

Note: I assumed ProductNumber is the unique identifier for each product (since it's a required field in ProductTypes). Adjust if you use a different unique key.

2. Define the CO2 Impact Logic

Next, let's formalize how associations affect ProductPoints, with guardrails to keep values within your 0-2 range:

Core Impact Rules

  • Positive Association: When two products are selected together, each other's ProductPoints increases by 1 (capped at 2).
  • Negative Association: When two products are selected together, each other's ProductPoints decreases by 1 (floored at 0).
  • Neutral Association: No change to either product's value.

Implementation for Calculations

Create a static calculator class to handle point adjustments, especially when adding new products to the selected list:

public static class ProductImpactCalculator
{
    // Calculate adjusted points for a single product based on selected peers
    public static int CalculateAdjustedPoints(Product targetProduct, List<Product> selectedProducts)
    {
        // Get the base CO2 value (adjust if a Product has multiple ProductTypes entries)
        int basePoints = targetProduct.ProductTypes.First().ProductPoints;
        int adjustedPoints = basePoints;

        foreach (var selectedProduct in selectedProducts)
        {
            var targetId = targetProduct.ProductTypes.First().ProductNumber;
            var selectedId = selectedProduct.ProductTypes.First().ProductNumber;

            // Skip the product itself
            if (targetId == selectedId) continue;

            // Apply association impact (default to neutral if no association exists)
            if (targetProduct.ProductAssociations.TryGetValue(selectedId, out var association))
                adjustedPoints = ApplyAssociationEffect(adjustedPoints, association);
            else
                adjustedPoints = ApplyAssociationEffect(adjustedPoints, AssociationType.Neutral);
        }

        // Ensure value stays within 0-2 bounds
        return Math.Clamp(adjustedPoints, 0, 2);
    }

    // Apply single association effect
    private static int ApplyAssociationEffect(int currentPoints, AssociationType type)
    {
        return type switch
        {
            AssociationType.Positive => currentPoints + 1,
            AssociationType.Negative => currentPoints - 1,
            _ => currentPoints
        };
    }

    // Batch-update all selected products' points (call this when adding a new product)
    public static void RefreshSelectedProductPoints(List<Product> selectedProducts)
    {
        // Calculate all new points first to avoid mid-update interference
        var pointUpdates = new Dictionary<long, int>();
        foreach (var product in selectedProducts)
        {
            var productId = product.ProductTypes.First().ProductNumber;
            pointUpdates[productId] = CalculateAdjustedPoints(product, selectedProducts);
        }

        // Apply the updates
        foreach (var product in selectedProducts)
        {
            var productId = product.ProductTypes.First().ProductNumber;
            product.ProductTypes.First().ProductPoints = pointUpdates[productId];
        }
    }
}

3. Manage Editable Associations

To let users modify associations later, add a simple manager class to handle setting, removing, and checking relationships:

public static class AssociationManager
{
    // Set a mutual association between two products (adjust to one-way if needed)
    public static void SetMutualAssociation(Product productA, Product productB, AssociationType type)
    {
        var idA = productA.ProductTypes.First().ProductNumber;
        var idB = productB.ProductTypes.First().ProductNumber;

        // Update A -> B association
        if (productA.ProductAssociations.ContainsKey(idB))
            productA.ProductAssociations[idB] = type;
        else
            productA.ProductAssociations.Add(idB, type);

        // Update B -> A association (since impacts are mutual per your requirement)
        if (productB.ProductAssociations.ContainsKey(idA))
            productB.ProductAssociations[idA] = type;
        else
            productB.ProductAssociations.Add(idA, type);
    }

    // Remove mutual association between two products
    public static void RemoveMutualAssociation(Product productA, Product productB)
    {
        var idA = productA.ProductTypes.First().ProductNumber;
        var idB = productB.ProductTypes.First().ProductNumber;

        productA.ProductAssociations.Remove(idB);
        productB.ProductAssociations.Remove(idA);
    }

    // Get the association type between two products
    public static AssociationType GetAssociation(Product productA, Product productB)
    {
        var idB = productB.ProductTypes.First().ProductNumber;
        return productA.ProductAssociations.TryGetValue(idB, out var type) 
            ? type 
            : AssociationType.Neutral;
    }
}

Note: If you need one-way associations (e.g., Product A boosts Product B but not vice versa), remove the code that updates the reverse association.

4. Example Workflow

Here's how this all comes together when selecting products and modifying associations:

// Load your 90 serialized products
List<Product> allProducts = LoadProductsFromXml(); // Your existing XML deserialization method
List<Product> selectedProducts = new List<Product>();

// Step 1: Add first product
var product1 = allProducts.First(p => p.ProductTypes.First().ProductNumber == 1);
selectedProducts.Add(product1);

// Step 2: Add second product and refresh points
var product2 = allProducts.First(p => p.ProductTypes.First().ProductNumber == 2);
selectedProducts.Add(product2);
ProductImpactCalculator.RefreshSelectedProductPoints(selectedProducts);

// Step 3: Modify their association and re-calculate
AssociationManager.SetMutualAssociation(product1, product2, AssociationType.Negative);
ProductImpactCalculator.RefreshSelectedProductPoints(selectedProducts);

// Step 4: Save updated associations back to XML (preserves edits)
SaveProductsToXml(allProducts); // Your existing XML serialization method

5. Serialization Notes

Since we used DataMember for the ProductAssociations dictionary, the DataContractSerializer will automatically serialize/deserialize these relationships. This means your edits will persist between sessions when you save/load the XML file.

内容的提问来源于stack exchange,提问作者J.Boehm

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.11 08:45:24