C# 数据结构(如字典)在点位于范围内时返回字符串

C# 数据结构(如字典)在点位于范围内时返回字符串,c#,sql,C#,Sql,我有一个SQL查询,它返回下表中的3列: 我正在搜索一个数据结构,在这个结构中我可以存储表,当点在中间时,它会将phasename返回给我 即300回报项目管理,360回报控制 “项目管理”=给定阶段数(300); “控制”=给定相数(360) 我会用SQL写 WHERE point IS BETWEEN y1 AND y2 public string givePhaseNameFor(int point) { return "Project Management } 是否有数据结

我有一个SQL查询,它返回下表中的3列:

我正在搜索一个数据结构,在这个结构中我可以存储表,当点在中间时,它会将phasename返回给我

即300回报项目管理,360回报控制

“项目管理”=给定阶段数(300); “控制”=给定相数(360)

我会用SQL写

WHERE point IS BETWEEN y1 AND y2

public string givePhaseNameFor(int point) 
{
   return "Project Management
}
是否有数据结构(如字典)?

类行
{
公共Y1{get;set;}
公共Y2{get;set;}
公共名称{get;set;}
}
var list=新列表();
//填写清单
var result=list.Where(o=>o.Y1
class行
{
公共Y1{get;set;}
公共Y2{get;set;}
公共名称{get;set;}
}
var list=新列表();
//填写清单

var result=list。其中(o=>o.Y1No)没有,但您可以使用如下内容:

public class RangeList<T>
{
    private List<T> list = new List<T>();
    public abstract int GetLower(T item);
    public abstract int GetUpper(T item);
    public T this[int index]
    {
        get
        {
            return list.SingleOrDefault(x => index >= GetLower(x) && index <= GetUpper(x));
        }
    }
    public void Add(T item)
    {
        if (list.Any(x => GetUpper(item) >= GetLower(x) && GetLower(item) <= GetUpper(x)))
            throw new Exception("Attempt to add item with overlapping range");
    }
}

public class Phase
{
    public int y1;
    public int y2;
    public string phasename;
}

public class PhaseList : RangeList<Phase>
{
    public override int GetLower(Phase item)
    {
        return item.y1;
    }
    public override int GetUpper(Phase item)
    {
        return item.y1;
    }
}

编辑:另一种方法是创建“RangeList”中可用的类必须实现的接口。这意味着您不需要为要使用的每种类型使用单独的继承列表类

public interface IRangeable
{
    int Lower { get; }
    int Upper { get; }
}

public class Phase : IRangeable
{
    public int y1;
    public int y2;
    public string phasename;

    int IRangeable.Lower => y1;
    int IRangeable.Upper => y2;
}

public class RangeList<T> where T : IRangeable
{
    private List<T> list = new List<T>();
    public T this[int index]
    {
        get
        {
            return list.SingleOrDefault(x => index >= ((IRangeable)x).Lower && index <= ((IRangeable)x).Upper);
        }
    }
    public void Add(T item)
    {
        if (list.Any(x => ((IRangeable)item).Higher >= ((IRangeable)x).Lower && ((IRangeable)item).Lower <= ((IRangeable)x).Upper))
            throw new Exception("Attempt to add item with overlapping range");
    }
}
公共接口IRangeable
{
整数下限{get;}
整数上限{get;}
}
公共类阶段:IRangeable
{
公共int y1;
公共int y2;
公共字符串相位名称;
int IRangeable.Lower=>y1;
int IRangeable.Upper=>y2;
}
公共类范围列表,其中T:IRangeable
{
私有列表=新列表();
公共T此[int索引]
{
得到
{

return list.SingleOrDefault(x=>index>=((IRangeable)x)。Lower&&index((IRangeable)项)。Higher>=((IRangeable)x)。Lower&&((IRangeable)项)。Lower没有,但您可以使用如下内容:

public class RangeList<T>
{
    private List<T> list = new List<T>();
    public abstract int GetLower(T item);
    public abstract int GetUpper(T item);
    public T this[int index]
    {
        get
        {
            return list.SingleOrDefault(x => index >= GetLower(x) && index <= GetUpper(x));
        }
    }
    public void Add(T item)
    {
        if (list.Any(x => GetUpper(item) >= GetLower(x) && GetLower(item) <= GetUpper(x)))
            throw new Exception("Attempt to add item with overlapping range");
    }
}

public class Phase
{
    public int y1;
    public int y2;
    public string phasename;
}

public class PhaseList : RangeList<Phase>
{
    public override int GetLower(Phase item)
    {
        return item.y1;
    }
    public override int GetUpper(Phase item)
    {
        return item.y1;
    }
}

编辑:另一种方法是创建“RangeList”中可用的类必须实现的接口。这意味着您不需要为要使用的每种类型使用单独的继承列表类

public interface IRangeable
{
    int Lower { get; }
    int Upper { get; }
}

public class Phase : IRangeable
{
    public int y1;
    public int y2;
    public string phasename;

    int IRangeable.Lower => y1;
    int IRangeable.Upper => y2;
}

public class RangeList<T> where T : IRangeable
{
    private List<T> list = new List<T>();
    public T this[int index]
    {
        get
        {
            return list.SingleOrDefault(x => index >= ((IRangeable)x).Lower && index <= ((IRangeable)x).Upper);
        }
    }
    public void Add(T item)
    {
        if (list.Any(x => ((IRangeable)item).Higher >= ((IRangeable)x).Lower && ((IRangeable)item).Lower <= ((IRangeable)x).Upper))
            throw new Exception("Attempt to add item with overlapping range");
    }
}
公共接口IRangeable
{
整数下限{get;}
整数上限{get;}
}
公共类阶段:IRangeable
{
公共int y1;
公共int y2;
公共字符串相位名称;
int IRangeable.Lower=>y1;
int IRangeable.Upper=>y2;
}
公共类范围列表,其中T:IRangeable
{
私有列表=新列表();
公共T此[int索引]
{
得到
{

return list.SingleOrDefault(x=>index>=((IRangeable)x)。Lower&&index((IRangeable)项)。Higher>=((IRangeable)x)。Lower&&((IRangeable)项)。Lower如果你想要速度,我会制作两个数组:

  • 包含起始范围的一个
  • 另一个包含名称的
然后首先填充阵列:

int nbRanges = //Get this info from the number of rows in you table
int[] range = new int[nbRanges];
string[] rangeNames = new string[nbRanges];
for (int i = 0; i < nbRanges; i++)
{
    range[i] = //Table.y1;
    rangeNames[i] = //Table.phasename;
}
int nbRanges=//从表中的行数中获取此信息
int[]范围=新的int[nbRanges];
string[]rangeNames=新字符串[nbRanges];
对于(int i=0;i
在此之后,查找名称很简单:

public string givePhaseNameFor(int point) 
{
    int index = 0;
    while (index + 1 < nbRanges)
    {
        if (point <= range[index + 1])
        {
            //This means that your point is in the current range
            break;
        }
        else
        {
            index++; //The point is not in this range
        }
    }
    //If we exit without having it found, index == nbRanges and we return the last value
    return rangeNames[index];
}
公共字符串givePhaseNameFor(int点)
{
int指数=0;
而(指数+1如果(点如果你想要速度,我会制作两个数组:

  • 包含起始范围的一个
  • 另一个包含名称的
然后首先填充阵列:

int nbRanges = //Get this info from the number of rows in you table
int[] range = new int[nbRanges];
string[] rangeNames = new string[nbRanges];
for (int i = 0; i < nbRanges; i++)
{
    range[i] = //Table.y1;
    rangeNames[i] = //Table.phasename;
}
int nbRanges=//从表中的行数中获取此信息
int[]范围=新的int[nbRanges];
string[]rangeNames=新字符串[nbRanges];
对于(int i=0;i
在此之后,查找名称很简单:

public string givePhaseNameFor(int point) 
{
    int index = 0;
    while (index + 1 < nbRanges)
    {
        if (point <= range[index + 1])
        {
            //This means that your point is in the current range
            break;
        }
        else
        {
            index++; //The point is not in this range
        }
    }
    //If we exit without having it found, index == nbRanges and we return the last value
    return rangeNames[index];
}
公共字符串givePhaseNameFor(int点)
{
int指数=0;
而(指数+1如果(点
Dictionary
?获取您得到的值,检查值在两者之间的位置,然后返回它?您在
Dictionary
回答中遇到的问题是什么确实,如果您说“当给定一个从y1(包括)到y2(不包括)的范围内的值时”,就会清楚得多@Vulpex:我强烈怀疑这里的条目列表比字典更好-这样OP就可以使用二进制搜索,而不必检查所有条目。当你永远不会按键查找时,使用字典是没有意义的。为什么你想要一本字典?使用
从@val>=y1 a的表中选择ProjectManagementND@val
Dictionary
?获取您得到的值,检查值在两者之间的位置,然后返回它?您在
Dictionary
中遇到的问题是什么?事实上,如果您说“当给定一个从y1(包含)到y2(不包含)的范围内的值时”@Vulpex:我强烈怀疑这里的条目列表比字典更好-这样OP就可以使用二进制搜索,而不必检查所有条目。当你永远不会按键查找时,使用字典是没有意义的。为什么你想要一本字典?使用
从@val>=y1 a的表中选择ProjectManagementND@val数据库将比this@TimSchmelter当然,问题是,我必须为20000个条目的列表执行此操作:/数据库将比this@TimSchmelter当然,问题是,我必须为20000个条目的列表执行此操作:/