2012-05-03 36 views
0

我正在寻找一种更有效的方法来构建多个数据库列的分号分隔列表。我现在使用的代码看起来像这样(和它的作品):访问多个数据库列的更有效方法

//Process List of things 
var things = DB.DbColumn_1.HasValue ? DB.DbColumn_1.Value.Equals(true) ? "thing 1;" : "" : ""); 
things += DB.DbColumn_2.HasValue ? DB.DbColumn_2.Value.Equals(true) ? "thing 2;" : "" : ""); 
things += DB.DbColumn_3.HasValue ? DB.DbColumn_3.Value.Equals(true) ? "thing 3;" : "" : ""); 
things += DB.DbColumn_4.HasValue ? DB.DbColumn_4.Value.Equals(true) ? "thing 4;" : "" : ""); 
// Remove final ';' from thing list if non-empty 
things = things.Length > 0 ? things.Substring(0, things.Length-1) : things; 

其实我有大约8列,过程 - 例如省去一些的那个。所以我有一大块难看的代码来构建一个简单的字符串。虽然这似乎工作得很好,但对于我正在尝试做的事情来说,它似乎有太多的代码。另外,在这种情况下,我应该谨慎使用“.Equals()”吗?

经过一番头脑风暴之后,我想出了没有比这更高效的任何东西,比如建立一个单独的函数来创建字符串本身。所有的列都是唯一的可为空的布尔值,并且所有的列都有唯一的字符串输出。

还是我有效地访问这些元素足够有效而不用担心它?

谢谢!

+0

倒叙帽子里的猫。事物1和事物2 ... –

+0

您可以编写一个查询,在一次读取中获取所有值,然后使用linq-to-object中的结果来创建字符串。 – frenchie

回答

2

DB.DbColumn_1.HasValue && DB.DbColumn_1.Value.Equals(true)是写入DB.DbColumn_1.GetValueOrDefault()的一种非常困难的方式,但它们在功能上是等同的。查看该Nullable<T>结构的详细信息(bool?相当于Nullable<bool>,这是你的数据库列的类型)在http://msdn.microsoft.com/en-us/library/1t3y8s4s(v=vs.80).aspxhttp://msdn.microsoft.com/en-us/library/b3h38hb0.aspx

您可以使用这些方法之一:

var sections = new List<string>(); 
if (DB.DbColumn_1.GetValueOrDefault()) sections.Add("thing 1"); 
if (DB.DbColumn_2.GetValueOrDefault()) sections.Add("thing 2"); 
//...other columns 
var things = string.Join(";", sections); 

或者:

var pairs = new List<Tuple<bool?, string>> 
{ 
    Tuple.Create(DB.DbColumn_1, "thing 1"), 
    Tuple.Create(DB.DbColumn_2, "thing 2") 
    //...other columns 
}; 
var things = string.Join(";", pairs.Where(x => x.Item1.GetValueOrDefault()).Select(x => x.Item2)); 

或设置pairs只有一次:

static readonly List<Tuple<Func<DBType, bool?>, string>> pairs = new List<Tuple<Func<DBType, bool?>, string>> 
    { 
     new Tuple<Func<DBType, bool?>, string>(d => d.DbColumn_1, "thing 1"), 
     new Tuple<Func<DBType, bool?>, string>(d => d.DbColumn_2, "thing 2") 
     //...other columns 
    }; 

void inSomeMethod() 
{ 
    var things = string.Join(";", pairs.Where(x => x.Item1(DB).GetValueOrDefault()).Select(x => x.Item2)); 
} 

这取决于当然的情况,但我最喜欢最后一个。如果声明的详细程度困扰你,(即重复Tuple<Func<DBType, bool?>, string>),你可以这样做:

class ReadDbBools : Tuple<Func<DBType, bool?>, string> 
{ 
    public ReadDbBools(Func<DBType, bool?> retrieveFunc, string ifTrue) : base(retrieveFunc, ifTrue) { } 
} 

static readonly List<ReadDbBools> pairs = new List<ReadDbBools> 
{ 
    new ReadDbBools(d => d.DbColumn_1, "thing 1"), 
    new ReadDbBools(d => d.DbColumn_2, "thing 2") 
    //...other columns 
}; 
0

你可以扩展你的LINQ到SQL模型一点点返回你所期望的价值,这样你就得到了部分出路:

public partial class Entity { 
    public string DbColumn_1_Display { 
     return (DbColumn_1 ?? false) ? "thing_1" : ""; 
    } 
    /*for each property*/ 
} 

,然后选择它,你可以做一些事情像这样:

var result = from db in DB 
      select new { 
        c1 = DbColumn_1_Display, 
        c2 = DbColumn_2_Display /*etc*/}; 
var string = string.Format("{0};{1};{2}/*...*/", result.c1, result.c2 /*...*/); 

不知道这是否使事情更容易。

0

好下手可空类型覆盖Equals方法等,而不是这个

DB.DbColumn_1.HasValue ? DB.DbColumn_1.Value.Equals(true) ? "thing 1;" : "" : "" 

你可以只写这个

DB.DbColumn_1.Equals(true) ? "thing1;" : "" 

而且使用string.Join是最后一个处理额外分号的更方便的方式,这留给你:

var things = string.Join(";", new [] 
    { 
     DB.DbColumn_1.Equals(true) ? "thing1" : null, 
     DB.DbColumn_2.Equals(true) ? "thing2" : null, 
     // etc... 
    }.Where(i => i != null)); 

这使得代码更易读,但不会真的做的非常多,以提高性能,因为这处理应该已经是相当快呢。

相关问题