Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/261.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 基于值选择多个集合的最佳匹配组合_C#_Entity Framework_Linq - Fatal编程技术网

C# 基于值选择多个集合的最佳匹配组合

C# 基于值选择多个集合的最佳匹配组合,c#,entity-framework,linq,C#,Entity Framework,Linq,我有一个.net核心web应用程序,供我们的员工使用,根据他们输入的余额将产品与客户匹配。有5种类型的产品。产品1必须作为主要产品包含在每个捆绑包中。其他4种产品将根据该价值与尽可能多的产品捆绑在一起。但产品1也有多个不同的价位。因此,假设客户能够负担产品1的最高价格点,但只有2个插件。我需要它降到产品1的下一个值并添加每个插件等。有人能给我的任何指导都会很有帮助。假设您有一个包含类型和价格的产品表 您可以将产品配置为类型1的产品和其他产品: var Prod1 = Products.Where

我有一个.net核心web应用程序,供我们的员工使用,根据他们输入的余额将产品与客户匹配。有5种类型的产品。产品1必须作为主要产品包含在每个捆绑包中。其他4种产品将根据该价值与尽可能多的产品捆绑在一起。但产品1也有多个不同的价位。因此,假设客户能够负担产品1的最高价格点,但只有2个插件。我需要它降到产品1的下一个值并添加每个插件等。有人能给我的任何指导都会很有帮助。

假设您有一个包含
类型和
价格的
产品表

您可以将
产品
配置为
类型
1的产品和其他产品:

var Prod1 = Products.Where(p => p.Type == 1);
var ProdNot1 = Products.Where(p => p.Type != 1);
使用一些扩展方法,您可以创建非1型产品的所有可能组合(如果您是从数据库提取,则必须在内存中执行此操作):

使用最低价格的1类产品:

var minPriceProd1 = Prod1.MinBy(p => p.Price);
您可以使用
CustBal
并猜测您对附加产品的预算:

var CustBal = 375;
var nonProd1BalGuess = CustBal - minPriceProd1.Price;
var finalProd1 = Prod1.Where(p => p.Price <= minPriceProd1.Price + allProdBalGuess).OrderByDescending(p => p.Price).First();
var nonProd1Bal = CustBal - finalProd1.Price;
然后,您可以猜测哪个附加组件组合将起作用,最大化类型数,优先考虑较低的类型,并采用最低价格:

var nonProd1Guess = AddOnCombos.Where(aoc => aoc.Price <= nonProd1BalGuess)
                           .OrderByDescending(aoc => aoc.Products.Count())
                           .ThenBy(aoc => aoc.Types)
                           .ThenBy(aoc => aoc.Price)
                           .FirstOrDefault();
然后计算类型1的最终产品以及附加产品的剩余量:

var CustBal = 375;
var nonProd1BalGuess = CustBal - minPriceProd1.Price;
var finalProd1 = Prod1.Where(p => p.Price <= minPriceProd1.Price + allProdBalGuess).OrderByDescending(p => p.Price).First();
var nonProd1Bal = CustBal - finalProd1.Price;

“尽可能多”是什么意思?在一个捆绑包中可以有任意产品的倍数吗?一般来说,减去最小产品1,首先减去其他产品的最小值,使用剩余的余额提升产品1等级。因此产品1有许多不同的价格点,因此产品1将始终作为主要产品包含在每个捆绑包中。其他每种产品都只有一种。产品是否有优先权,或者优先权是否包括尽可能多的产品,最多4种?如果您尽可能多地包含,是否有更高定价的优先权,例如,是否更倾向于使用比类型3更昂贵的类型2,或者这是否重要?是的,因此产品2的权重将高于产品3,产品3的权重将高于产品4等。如果您拥有所有5种产品(或4或3),并且剩余余额,是获得更高的Prod1,还是更高的Prod2,还是什么?
var finalProd1 = Prod1.Where(p => p.Price <= minPriceProd1.Price + allProdBalGuess).OrderByDescending(p => p.Price).First();
var nonProd1Bal = CustBal - finalProd1.Price;
var nonProd1 = AddOnCombos.Where(aoc => aoc.Price <= nonProd1Bal)
                           .OrderByDescending(aoc => aoc.Products.Count())
                           .ThenBy(aoc => aoc.Types)
                           .ThenByDescending(aoc => aoc.Price)
                           .ThenByDescending(aoc => Enumerable.Range(2, 5).Select(t => aoc.Products.FirstOrDefault(p => p.Type == t)?.Price ?? 0), new SeqCompare<double>())
                           .FirstOrDefault();
public static class IEnumerableExt {
    public static int SeqCompareTo<T>(this IEnumerable<T> s1, IEnumerable<T> s2) => SequenceCompare(s1, s2);

    public static int SequenceCompare<T>(IEnumerable<T> source1, IEnumerable<T> source2) {
        // You could add an overload with this as a parameter
        IComparer<T> elementComparer = Comparer<T>.Default;
        using (IEnumerator<T> iterator1 = source1.GetEnumerator())
        using (IEnumerator<T> iterator2 = source2.GetEnumerator()) {
            while (true) {
                bool next1 = iterator1.MoveNext();
                bool next2 = iterator2.MoveNext();
                if (!next1 && !next2) // Both sequences finished
                    return 0;
                if (!next1) // Only the first sequence has finished
                    return -1;
                if (!next2) // Only the second sequence has finished
                    return 1;
                // Both are still going, compare current elements
                int comparison = elementComparer.Compare(iterator1.Current,
                                                         iterator2.Current);
                // If elements are non-equal, we're done
                if (comparison != 0)
                    return comparison;
            }
        }
    }
}

public class SeqCompare<T> : IComparer<IEnumerable<T>> {
    public int Compare(IEnumerable<T> x, IEnumerable<T> y) => x.SeqCompareTo(y);
}