2012-05-03 98 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)); 

這使得代碼更易讀,但不會真的做的非常多,以提高性能,因爲這處理應該已經是相當快呢。

相關問題