2017-07-21 24 views
0

在我創建的黑客組織遊戲的wpf應用程序中訪問列表中的內容時出現問題。在WPF應用程序中從SQL Server中選擇數據

基本上我從SQL Server 2016讀取,然後將其添加到我的用戶集合列表中。後來當我在顯示器中使用我的列表時,他們都在那裏。

但是,當我使用foreach循環來設置一個臨時用戶等於一個找到的用戶名時,它只能找到硬編碼的用戶,而不是使用從SQL Server讀取的數據添加的用戶。需要幫忙。

SQL Server讀取的代碼:

using (connect = new SqlConnection(connetionString)) 
{ 
    connect.Open(); 

    string readString = "select * from Users"; 
    SqlCommand readCommand = new SqlCommand(readString, connect); 

    using (SqlDataReader dataRead = readCommand.ExecuteReader()) 
    { 
     if (dataRead != null) 
     { 
      while (dataRead.Read()) 
      { 
       tempEmail = dataRead["Email"].ToString(); 
       tempName = dataRead["Name"].ToString(); 

       UserCollection.addUser(tempEmail, tempName); 
      } 
     } 
    } 

    connect.Close(); 
} 

UserCollection相關部分

private static List<User> UserList = new List<User>(); 

// add a user 
public static void addUser(string email, string name) 
{ 
     UserList.Add(new User(email, name, 0, "unset", false, false, false, false, false, false, 
      false, "", false, false, false, 0, 0)); 
} 

//return list of users for use elsewhere 
public static List<User> ReturnUserList() 
{ 
     return UserList; 
} 

使用列表的設置tempPlayer在WPF窗口的代碼,其中的列表

PlayersList = UserCollection.ReturnUserList(); 

// tempPlayer = UserCollection.ReturnAUser(sessionUser); 
foreach (var element in PlayersList) 
{ 
    if (element.UserName == sessionUser) 
    { 
     tempPlayer = element; 
    } 
} 

例作品。

// set listing of current players 
ListOfPlayers = UserCollection.ReturnUserList(); 

var tempList = from player in ListOfPlayers 
       where player.UserBlocked == false 
       select new 
         { 
         Name = player.UserName, 
         Email = player.UserEmail, 
         }; 

this.PlayerListBox.ItemsSource = tempList; 

硬編碼的用戶添加工作正常,並且可以通過foreach語句從我app.xaml.cs

UserCollection.addUser("g", "Tom"); 
+0

這裏有很多東西在這裏沒有顯示,就像任何UserCollection一樣。 – tadman

+0

我可以添加更多,但是整套代碼是1000行+ – LINQtothepast

+1

借調,很難在沒有看到其他課程的情況下發現問題的位置。它看起來像你的實現比它需要更復雜一點 - 使用一個方法來返回你的用戶列表,而不是一個屬性,例如。我們需要的僅僅是一個簡單的例子,因此您在數據庫邏輯中調用的任何變量/方法。我們需要一個可驗證的例子來工作,但不是所有的1000多行。 – Alex

回答

1

首先可以發現,在那裏你爲什麼需要一個靜態方法來添加用戶一個理由收藏?即使您需要通過靜態訪問者訪問列表,您最好在同一個類上使用靜態屬性來讀取數據塊

下面的代碼段應該有一定的幫助。

public class UserManagement { 

    //Static property 
    private static List<User> _users; 

    public static List<User> Users { 
     get { 
      if (_users == null) { 
       _user = new List<User>(); 
      } 
      return _users; 
     } 
     set { } 
    } 

    //Static load method must be called before accessing Users 
    public static void LoadDBUsers() { 


     using (SqlConnection connection = new SqlConnection(connetionString)) { 
      connection.Open(); 
      string readString = "select * from Users"; 
      using (SqlCommand command = new SqlCommand(readString, connection)) { 
       using (SqlDataReader reader = command.ExecuteReader()) { 
        while (reader.Read()) { 
         String tempEmail = reader["Email"].ToString(); 
         String tempName = reader["Name"].ToString(); 
         User user = new User(tempEmail, tempName, 0, "unset", false, false, false, false, false, false, false, "", false, false, false, 0, 0)); 
         users.Add(user); 
        } 
       } 
      } 
     } 
    } 
} 

要從其他類中使用:

UserManagement.LoadDBUsers(); 
var dbUsers = UserManagement.Users; 

如果有用戶的另一份名單(從文件說),你可以添加一個裝載方法,你的類將處理爲你。

如果在某些時候你需要清除下來的用戶列表,你可以簡單地將其設置爲一個新的實例...

UserManagement.Users = new List<User>(); 

一個稍微好一點的方式做這將是去除靜電屬性Users首先,將方法定義更改爲從LoadDBUsers方法返回List<User> - 例如。

public static List<User> LoadDBUsers() { 
    List<User> Users = new List<User>(); 

    //Handle the database logic as in the previous example.. 
    //Then at the end of the method.. 
    return Users; 
} 

,並調用如下

List<User> dbUsers = UserManagement.LoadDBUsers(); 

採用後一種方法,你不必擔心你的代碼保持靜態屬性的多個位置。只需調用並將其分配給一個變量。 它還具有以下優點:您將始終從數據庫獲取最新的用戶列表,而無需在從靜態屬性訪問列表之前清除並重新加載列表。

不使用全局靜態屬性的一個附加優點是它可以避免潛在的內存問題。如果垃圾收集器的引用處於打開狀態,則靜態屬性可能難以處理。 使用實例變量時,很明顯,當一個超出範圍並且不再被引用時,但是使用靜態變量時,引用有時不會在程序結束之前處理。

在很多情況下,這不是問題,但在較大的系統中調試會很麻煩。

+0

我會嘗試這種方法,然後最有可能檢查標記它。tempEmail和tempName都是在string類型的前面聲明的。我應該補充一點。我會嘗試重寫數據庫是如何調用的。所以我認爲靜態打字在大多數情況下都是好的,我猜我會少用一點。它的默認設置我始終使用 – LINQtothepast

+0

@DerekBlankinship如果你需要一個存儲一些數據但是可以從應用程序中的多個地方訪問的對象,我建議你查看Singleton設計模式。它使用靜態方法調用,但是當第一次訪問時,它會創建一個自己的實例並返回它。如果已經創建了一個實例,則該靜態調用將返回該實例。它仍然可能存在引用沒有被銷燬的問題,但是它更容易管理和調試。靜態對象是有用的,但很容易變得笨拙。 – Alex

0
tempEmail = dataRead["Email"].ToString(); 
tempName = dataRead["Name"].ToString(); 

tempEmail,tempName你是

using (connect = new SqlConnection(connetionString))

的tempEmail和tempName是引用類型,因此,如果環路是第一個記錄之後第二次循環tempName添加和tempEmail值更新也曾經上述聲明因爲它也指向相同的內存。所以數據是重複的記錄列表,用戶不能正確添加用戶。

所以,你可以改變你的代碼

var tempEmail = dataRead["Email"].ToString(); 
var tempName = dataRead["Name"].ToString(); 

和tempEmail之前,tempName using語句之前刪除的聲明。

我希望這對你有幫助。

+0

假設這些類型是字符串,並且在類中的某處定義爲靜態,則爲它們分配一個值將僅替換現有值。 – Alex

+0

雅他們已經被定義爲私人字符串。改變他們到var仍然有不幸的是相同的錯誤。我目前還沒有完全做好編碼工作,但我會嘗試亞歷克斯的答案。謝謝你的幫助 – LINQtothepast

0

我相信你的while循環導致了這個問題。由於「使用」已生效,因此全局變量「tempEmail」&「tempName」保留爲空。我在我的末端使用MySql測試了代碼,此解決方案非常有效。

private List<User> PlayersList; 

public Tester() 
     { 
      using (SqlConnection connect = new SqlConnection(connectionString)) 
      { 
       connect.Open(); 

       string readString = "select * from user"; 

       SqlCommand readCommand = new SqlCommand(readString, connect); 

       using (SqlDataReader dataRead = readCommand.ExecuteReader()) 
       { 
        if (dataRead != null) 
        { 
         while (dataRead.Read()) 
         { 
          string tempEmail = dataRead["Email"].ToString(); 
          string tempName = dataRead["Name"].ToString(); 

          UserCollection.addUser(tempEmail, tempName); 
         } 
        } 
       } 

       connect.Close(); 
      } 

      PlayersList = UserCollection.ReturnUserList(); 
     } 

     public class User 
     {  
      public string email; 
      public string name; 

      // A constructor that takes parameter to set the properties 
      public User(string e, string n) 
      { 
       email = e; 
       name = n; 
      } 
     } 


     public static class UserCollection 
     {  
      private static List<User> UserList = new List<User>(); 

      // add a user 
      public static void addUser(string email, string name) 
      { 
       UserList.Add(new User(email, name)); 
      } 

      //return list of users for use elsewhere 
      public static List<User> ReturnUserList() 
      { 
       return UserList; 
      } 
     } 

這是關注的領域。

while (dataRead.Read()) 
{ 
    //Set local variable during while loop 
    string tempEmail = dataRead["Email"].ToString(); 
    string tempName = dataRead["Name"].ToString(); 

    UserCollection.addUser(tempEmail, tempName); 
} 
相關問題