小编典典

有没有办法遍历我的sql结果并将某些名称/值对存储在C#中的其他位置?

sql

我有一个很大的结果集,它来自一个非常复杂的SQL查询。这些值中的astring代表一个位置(以后将帮助我确定该值所来自的页面位置),anint是一个基于行中其他值为每行计算的优先级数,另一个string包含一个值我必须记得以后再显示。

问题在于sql查询是如此复杂(它具有UNIONS,JOINS和带有别名的复杂计算),以至于在不弄乱它的工作方式的情况下,我在逻辑上不能将其他任何内容放入其中。

可以说,尽管在查询完成并执行了计算之后,我需要一些可能由聚合函数解决的东西,但这不是一个选择,因为所有列都不来自其他聚合函数。

关于如何遍历结果,我已经动了好几天的脑筋,将一对值存储在一个列表中(或以某种方式将两个单独的列表捆绑在一起),其中一个值是每个位置的所有优先级值的总和并且另一个值是一个不同的位置值(即,在循环遍历结果时,它将不会创建具有与以前使用的位置值相同的另一个列表项,但是,它仍然需要所有其他值的总和)来自相同位置的优先级值)。同样,结果需要按降序排列优先级(因此,使用两个列表会出现问题)。

例子:

编辑: 我忘记了,保留的值应该是sql查询中具有最高优先级的行中的值。

如果我得到以下结果:

  location                      priority                               value

--------------------------------------------------------------------------------
   page1                           1                                  some text!
   page2                           3                                  more text!
   page2                           4                               even more text!
   page3                           3                                  text again
   page3                           1                                     text
   page3                           1                              still more text!
   page4                           6                                     text

如果我能够做自己想做的事,那么在迭代之后(并按此顺序),我将能够实现以下目标:

  location                      priority                               value

--------------------------------------------------------------------------------
   page2                           7                               even more text!
   page4                           6                                    text
   page3                           5                                  text again
   page1                           1                                  some text!

我已经进行了一个又一个的研究,但是绝对没有什么真正可以解决这个难题的。

对于强大的C#语言,我要问的内容是否太难了?

我考虑过的事情:

遍历sql结果并检查每个位置是否重复,我将所有优先级值加在一起,并将这两个加值存储在两个或三个单独的列表中。

为什么我仍然需要帮助

我不能使用foreach,因为逻辑没有展开,并且我不能使用for循环,因为我无法访问IEnumerable(或存储从Database.Open.Query()索引返回的内容的任何类型。(这很有意义)。
,当然)。此外,我需要优先排序,但不能使一个列表与其他列表不同步。


使用LINQ选择并存储我需要的东西

为什么我仍然需要帮助

我根本不了解LINQ,这主要是因为我不理解lambda表达式(无论我如何阅读它)。


使用实例化的类存储名称/值对

为什么我仍然需要帮助

我不仅希望对这种事情进行排序是不可能的,而且尽管现在我要如何.cs在带有WebMatrix环境的C#.net网页中使用文件,但我主要只使用过静态类,并且还需要一些复习关于构造函数以及如何进行适当设置。


以某种方式使此功能适合已经相当大且复杂的SQL查询

为什么我仍然需要帮助

虽然这可能是我理想的功能所在,但我再次强调这不是一种选择。我曾尝试使用聚合函数,但仅收到一条错误消息,说明并非所有其他列都来自聚合函数。


根据第一个查询的结果集中的值进行另一个查询

为什么我仍然需要帮助

我不能仅基于一个列(即位置)来选择不同的结果。


假设我可以正确理解循环逻辑,将值存储在3维数组中

为什么我仍然需要帮助

我无法声明该数组,因为在使用它之前我不知道它的所有维。


阅读 52

收藏
2021-04-28

共1个答案

小编典典

您的帖子以多种方式使我感到惊讶,例如说“主要使用静态类”和“期望实例化一个类/对象是不可能的”。我只能用查尔斯·巴贝奇(Charles
Babbage)的话回答:

我不能正确地理解可能引起这种问题的那种混乱的观念。

无论如何..正如您说的那样,您很难找到lambda,让我们以经典的“手动”方式来跟踪问题。

假设您有一个包含位置和优先级的ROWS列表。

List<DataRow> rows = .... ; // datatable, sqldatareader, whatever

您说您需要:

  • 唯一位置列表
  • 与汇总优先级配对的位置“列表”

让我们从第一个目标开始。

为了收集唯一的“值”列表,HashSet非常完美:

HashSet<string> locations = new HashSet<string>();
foreach(var row in rows)
    locations.Add( (string)rows["LOCATION"] );

好,仅此而已。之后,locations哈希集将仅记住所有唯一位置。“添加”不会导致重复的元素。HashSet检查并“唯一化”其内部的所有值。小棘手的事情是哈希集没有[index]运算符。您必须枚举散列集才能获取值:

foreach(string loc in locations)
{
    Console.WriteLine(loc);
}

或将其转换/重写为列表:

List<string> locList = new List<string>(locations);
Console.WriteLine(locList[2]); // of course, assuming there were at least three..

让我们达到第二个目标。

为了收集与某些事物(例如“逻辑键”)相关的值的列表,aDictionary<Key,Val>可能会有用。它允许您将“值”与一些“键”进行存储/关联,即:

Dictionary<string, double> dict = new Dictionary<string, double>();
dict["mamma"] = 123.45;
double d = dict["mamma"]; // d == 123.45

dict [“ mamma”] + = 101; // 可能的!double e = dict [“ mamma”]; // d == 224.45

但是,当您尝试从 未知键* 读取数据 时,它具有 抛出 异常的行为: ***

Dictionary<string, double> dict = new Dictionary<string, double>();
dict["mamma"] = 123.45;
double d = dict["daddy"]; // throws KeyNotBlarghException

dict [“ daddy”] + = 101; //也会抛出!尝试读取旧值/当前值!

因此,对于它尚不知道的“键”,必须非常小心。值得一提的是,您始终可以询问字典是否已经知道密钥:

Dictionary<string, double> dict = new Dictionary<string, double>();
dict["mamma"] = 123.45;
bool knowIt = dict.ContainsKey("daddy"); // == false

因此,您可以在未知时轻松检查并初始化:

Dictionary<string, double> dict = new Dictionary<string, double>();
bool knowIt = dict.ContainsKey("daddy"); // == false
if( !knowIt )
    dict["daddy"] = 5;

dict["daddy"] += 101; // now 106

所以..让我们尝试总结优先位置:

Dictionary<string, double> prioSums = new Dictionary<string, double>();
foreach(var row in rows)
{
    string location = (string)rows["LOCATION"];
    double priority  = (double)rows["PRIORITY"];

    if( ! prioSums.ContainsKey(location) )
        // make sure that dictionary knows the location
        prioSums[location] = 0.0;

    prioSums[location] += priority;
}

而且,真的,仅此而已。现在,prioSums遗嘱将知道所有位置和所有优先级的总和:

var sss = prioSums["NewYork"];  // 9123, assuming NewYork was some location

但是,必须对所有位置进行硬编码将毫无用处。因此,您还可以 向字典询问当前知道哪些键

foreach(string key in prioSums.Keys)
    Console.WriteLine(key);

您可以立即使用它:

foreach(string key in prioSums.Keys)
{
    Console.WriteLine(key);
    Console.WriteLine(prioSums[key]);
}

应该会打印所有位置及其所有金额。

您可能已经注意到了一件有趣的事情:字典可以告诉您它记住了哪些键。因此,您 不需要
第一个目标中的HashSet。只需将“字典”中的优先级进行汇总,即可免费获得唯一的位置列表:只需向dict索取其键即可。

编辑:

我注意到您还有其他一些请求(例如降序排列或查找最高优先值),但我想我现在将其保留。如果您了解我是如何使用词典来收集优先级的,那么您将轻松构建类似的内容Dictionary<string,string>来收集位置的最高排名值。如果仅从字典中取出值并将它们作为ie列表进行排序,那么“降序”将非常容易实现。因此,我现在将其略过。

2021-04-28