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

标签 c# sql linq list webmatrix

我有一个很大的结果集,来自一个非常复杂的SQL查询。这些值中有一个string表示一个位置(以后将帮助我确定该值来自的页面位置),一个int是根据该行的其他值为每行计算的优先级数字,另一个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表达式(无论我怎么读它)。



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

为什么我仍然需要帮助

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



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

为什么我仍然需要帮助

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



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

为什么我仍然需要帮助

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



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

为什么我仍然需要帮助

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

最佳答案

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


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


无论如何..正如您说的那样,您很难找到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..


让我们达到第二个目标。

要收集与某些事物的行为相关的值列表,例如“逻辑键”,Dictionary<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 [“爸爸”] + = 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>来收集位置的最高排名值。如果仅从字典中取出这些值并将它们作为一个i.e.列表进行排序,那么“降序”就非常容易实现。所以我现在将其略过。

关于c# - 有没有办法遍历我的sql结果并将某些名称/值对存储在C#中的其他位置?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17604201/

相关文章:

c# - 如何关闭已在目录中打开的文件

c# - 简单的 SELECT WHERE LINQ 查询列表

php - WooCommerce:使用 SQL 查询获取产品类别的购买商品

sql - 这些日期 where 子句有什么区别?

linq - 将字符串与包含中的拆分进行比较 - LINQ

c# - "Object reference not set to an instance of an object error"添加具有 Entity Framework 多对多关系的项目时

c# - MS Graph - LINQ 查询返回不正确的结果

c# - 构建用于测试的 HttpContext,如何指定 HttpRequest 是 POST?

c# - 合并排序实现查询

php - 当数据库结构在版本之间发生变化时如何升级Magento?