我有一张桌子" GEM"在具有唯一列 SPName 的数据库中。 每个记录的值由一个char和数字示例
组成F12,T16,K15,F10,K14,T9,T7
我想在选定的号码之前找到号码 例如:
输入:F12输出:F10
输入:T9输出:T7
输入:T16输出:T9
我正在考虑删除任何无数字,然后在输入数字之前对每个数字进行数据库搜索,但听起来就像是性能不佳。
Gem gem;
for(i= input; i>0; i--)
{
gem = Uow.Gems.GetAll().FirstOrDefault(x=> RemoveChar(x.SpName) == input)
If(gem!=null) break;
}
任何提示?
答案 0 :(得分:1)
一种丑陋的方式(无需例外处理等......)来做你想做的事情:
重要提示:请注意,最好的方法是通过添加 juharr 告诉您的列来更改数据库。
List<string> ints = new List<string>();
ints.Add("F12");
ints.Add("T16");
ints.Add("K15");
ints.Add("F10");
ints.Add("K14");
ints.Add("T9");
ints.Add("T7");
var ordered = ints.Select((s, i) => new
{
nb = int.Parse(s.Substring(1)),
text = s.Substring(0, 1),
val = s,
}).OrderBy(arg => arg.text).ThenBy(arg => arg.nb).ToList();
var index = ordered.FindIndex(arg => arg.val == "T16");
Console.WriteLine(ordered[index - 1].val);
Console.ReadLine();
答案 1 :(得分:1)
我认为这将返回你所追求的价值;
public string GetPrevious(string value)
{
var list = new[]
{
new {SPName = "F12"},
new {SPName = "T16"},
new {SPName = "K15"},
new {SPName = "F10"},
new {SPName = "K14"},
new {SPName = "T9"},
new {SPName = "T7"}
};
return
list.Where(
l => l.SPName.ToCharArray().First() == value.ToCharArray().First() &&
GetValue(l.SPName) < GetValue(value)).OrderByDescending(l => GetValue(l.SPName)).First().SPName;
}
public int GetValue(string value)
{
return int.Parse(value.Substring(1, value.Length - 1));
}
不幸的是,很难知道在没有原始表数据的情况下,这将与多个值一起运行的速度有多快(我不建议你发布它)。
答案 2 :(得分:1)
这个怎么样,不确定性能,但是应该在SQL中给你一个SPName LIKE 'T%@'
所以应该使用索引:
var input = "T9";
var Gem = Uow.Gems.Where
(g => g.SPName.StartsWith(input.Substring(0,1)) &&
Convert.ToInt32(g.SPName.Substring(1)) <
Convert.ToInt32(input.Substring(1)))
.OrderByDescending(g => Convert.ToInt32(g.SPName.Substring(1)))
.Take(1);
我认为这应该生成这个SQL:
-- Region Parameters
DECLARE @p0 VarChar(1000) = 'F%'
DECLARE @p1 Int = 1
DECLARE @p2 Int = 12
DECLARE @p3 Int = 1
-- EndRegion
SELECT TOP (1) [t0].[SPName]
FROM [Gem] AS [t0]
WHERE ([t0].[SPName] LIKE @p0) AND ((CONVERT(Int,SUBSTRING([t0].[SPName], @p1 + 1, CONVERT(Int,DATALENGTH([t0].[SPName]))))) < @p2)
ORDER BY CONVERT(Int,SUBSTRING([t0].[SPName], @p3 + 1, CONVERT(Int,DATALENGTH([t0].[SPName])))) DESC
答案 3 :(得分:1)
我建议使用一个简单的缓存来填充所有宝石并使用comparer对它们进行排序。
// Use your Uow.Gems.GetAll() list of gems
string[] gems = new string[] { "F12", "T16", "K15", "F10", "K14", "T9", "T7", "A12", "A11" };
string input = "A12";
//Cache it something like this Uow.Gems.GetAll().OrderBy(x => x, new GemComparer()).ToList()
var cacheGems = gems.OrderBy(x => x, new GemComparer());
foreach (var thing in cacheGems)
{
Console.WriteLine(thing);
}
var previous = cacheGems.TakeWhile(x => x != input).LastOrDefault();
var next = cacheGems.SkipWhile(x => x != input).Skip(1).FirstOrDefault();
Console.WriteLine(previous);
Console.WriteLine(next);
如果没有找到将会是空的
A11
A12
F10
F12
K14
K15
T16
T7
T9'
输出:上一个:A11,下一个F10
public class GemComparer : IComparer<string>
{
public int Compare(string s1, string s2)
{
if (IsNumeric(s1) && IsNumeric(s2))
{
if (Convert.ToInt32(s1) > Convert.ToInt32(s2)) return 1;
if (Convert.ToInt32(s1) < Convert.ToInt32(s2)) return -1;
if (Convert.ToInt32(s1) == Convert.ToInt32(s2)) return 0;
}
if (IsNumeric(s1) && !IsNumeric(s2))
return -1;
if (!IsNumeric(s1) && IsNumeric(s2))
return 1;
return string.Compare(s1, s2, true);
}
public static bool IsNumeric(object value)
{
try
{
int i;
return int.TryParse(value.ToString(), out i);
}
catch (FormatException)
{
return false;
}
}
}