因此,我必須讀取 MSSQL 資料庫中的所有餐廳記錄,并且每個餐廳都有一個表格串列。我的問題在于我知道如何閱讀一個餐廳行:
public Restaurant GeefRestaurant(int id)
{
using (SqlCommand cmd = _connection.CreateCommand())
{
try
{
_connection.Open();
string naam;
string email;
string telefoonnummer;
int postcode;
string gemeente;
string straat;
string huisnummer;
Keuken keuken;
int tafelnummerOld = -1;
int tafelnummer = 0;
int aantalPlaatsen = 0;
bool isBezet = false;
bool first = true;
Locatie l = null;
Restaurant r = null;
List<Tafel> tafels = new();
cmd.CommandText = $"select r.Id RestaurantId, r.naam, r.email, r.telefoonnummer, r.keuken, l.id locatieid, l.postcode, l.gemeente, l.straat, l.huisnummer, t.Tafelnummer, t.aantalplaatsen, t.isbezet "
$"from Restaurant r "
$"left join locatie l on r.locatieid = l.id "
$"left join tafel t on r.id = t.restaurantid "
$"where r.id = {id}";
SqlDataReader reader = cmd.ExecuteReader();
while (reader.Read())
{
if (r == null)
{
postcode = (int)reader["Postcode"];
gemeente = (string)reader["Gemeente"];
straat = reader["Straat"] == DBNull.Value ? null : (string)reader["Straat"];
huisnummer = reader["Huisnummer"] == DBNull.Value ? null : (string)reader["Huisnummer"];
keuken = (Enum.Parse<Keuken>((string)reader["keuken"]));
naam = (string)reader["naam"];
email = (string)reader["Email"];
telefoonnummer = (string)reader["telefoonnummer"];
l = new(postcode, gemeente, straat, huisnummer);
l.ZetId((int)reader["LocatieId"]);
r = new(naam, l, telefoonnummer, email, keuken);
r.ZetId((int)reader["RestaurantId"]);
}
if (!reader.IsDBNull(reader.GetOrdinal("Tafelnummer"))) // heeft tafels
{
tafelnummer = (int)reader["Tafelnummer"];
if (tafelnummer != tafelnummerOld)
{
// Nieuwe tafel of de eerste
if (tafelnummerOld > 0)
{
// Maak tafel, einde bereikt
Tafel t = new(tafelnummerOld, aantalPlaatsen, isBezet);
r.VoegTafelToe(t);
}
first = true;
tafelnummerOld = tafelnummer;
}
if (first)
{
aantalPlaatsen = (int)reader["AantalPlaatsen"];
isBezet = (bool)reader["IsBezet"];
first = false;
}
}
}
reader.Close();
if (tafelnummer > 0)
{
Tafel t = new(tafelnummer, aantalPlaatsen, isBezet);
r.VoegTafelToe(t);
}
return r;
}
catch (Exception ex)
{
throw new RestaurantRepositoryException("GebruikerRegistreren - repo", ex);
}
finally
{
_connection.Close();
}
}
}
但是我不完全知道如何在代碼中讀取所有這些,我知道 sql 命令,我嘗試了很多東西,但它們都沒有做它應該做的事情:/。我想要的是開始讀取餐廳行,讀出所有表格,然后繼續下一個,直到讀取所有資料。
我試過這樣的東西,但這不起作用......
public IReadOnlyList<Restaurant> GeefAlleRestaurants()
{
using (SqlCommand cmd = _connection.CreateCommand())
{
try
{
_connection.Open();
string naam;
string email;
string telefoonnummer;
int postcode;
string gemeente;
string straat;
string huisnummer;
Keuken keuken;
int restaurantIdOld = -1;
int restaurantId = 0;
int tafelnummerOld = -1;
int tafelnummer = 0;
int aantalPlaatsen = 0;
bool isBezet = false;
bool first = true;
bool firstRestaurant = true;
Locatie l = null;
List<Restaurant> restaurants = new();
//Restaurant r = null;
List<Tafel> tafels = new();
cmd.CommandText = $"select r.Id RestaurantId, r.naam, r.email, r.telefoonnummer, r.keuken, l.id locatieid, l.postcode, l.gemeente, l.straat, l.huisnummer, t.Tafelnummer, t.aantalplaatsen, t.isbezet "
$"from Restaurant r "
$"left join locatie l on r.locatieid = l.id "
$"left join tafel t on r.id = t.restaurantid";
SqlDataReader reader = cmd.ExecuteReader();
//TODO!
while (reader.Read())
{
if (!reader.IsDBNull(reader.GetOrdinal("RestaurantId"))) // heeft restaurants
{
restaurantId = (int)reader["RestaurantId"];
if (restaurantId != restaurantIdOld)
{
// Nieuwe restaurant of het eerste
if (restaurantIdOld > 0)
{
// Maak restaurant, einde bereikt
postcode = (int)reader["Postcode"];
gemeente = (string)reader["Gemeente"];
straat = reader["Straat"] == DBNull.Value ? null : (string)reader["Straat"];
huisnummer = reader["Huisnummer"] == DBNull.Value ? null : (string)reader["Huisnummer"];
keuken = (Enum.Parse<Keuken>((string)reader["keuken"]));
naam = (string)reader["naam"];
email = (string)reader["Email"];
telefoonnummer = (string)reader["telefoonnummer"];
r = new(naam, l, telefoonnummer, email, keuken);
if (reader.HasRows)
{
if (!reader.IsDBNull(reader.GetOrdinal("Tafelnummer")))
{
tafelnummer = (int)reader["Tafelnummer"];
if (tafelnummer != tafelnummerOld)
{
if (tafelnummerOld > 0)
{
Tafel t = new(tafelnummer, aantalPlaatsen, isBezet);
r.VoegTafelToe(t);
}
tafelnummerOld = tafelnummer;
aantalPlaatsen = (int)reader["aantalplaatsen"];
isBezet = (bool)reader["isbezet"];
}
}
}
restaurants.Add(r);
}
firstRestaurant = true;
restaurantIdOld = restaurantId;
if (firstRestaurant)
{
naam = (string)reader["naam"];
email = (string)reader["Email"];
telefoonnummer = (string)reader["telefoonnummer"];
postcode = (int)reader["Postcode"];
gemeente = (string)reader["Gemeente"];
straat = reader["Straat"] == DBNull.Value ? null : (string)reader["Straat"];
huisnummer = reader["Huisnummer"] == DBNull.Value ? null : (string)reader["Huisnummer"];
keuken = (Enum.Parse<Keuken>((string)reader["keuken"]));
l = new(postcode, gemeente, straat, huisnummer);
l.ZetId((int)reader["LocatieId"]);
r = new(naam, l, telefoonnummer, email, keuken);
r.ZetId((int)reader["RestaurantId"]);
if (reader.HasRows)
{
if (!reader.IsDBNull(reader.GetOrdinal("Tafelnummer")))
{
tafelnummer = (int)reader["Tafelnummer"];
if (tafelnummer != tafelnummerOld)
{
if (tafelnummerOld > 0)
{
Tafel t = new(tafelnummer, aantalPlaatsen, isBezet);
r.VoegTafelToe(t);
}
tafelnummerOld = tafelnummer;
aantalPlaatsen = (int)reader["aantalplaatsen"];
isBezet = (bool)reader["isbezet"];
}
}
}
restaurants.Add(r);
}
}
}
}
reader.Close();
return restaurants;
}
catch (Exception ex)
{
throw new RestaurantRepositoryException("GebruikerRegistreren - repo", ex);
}
finally
{
_connection.Close();
}
}
}
我還嘗試創建另一種回傳串列的方法,這樣我就可以使用此方法而不是嘗試從資料庫中獲取所有 Tafel 記錄,但我收到一個錯誤,表明連接已打開,我不知道這是否好實踐...
uj5u.com熱心網友回復:
如果您沒有明確指定一個 SQL 查詢,則不能保證以任何特定順序回傳記錄。由于您想在餐廳 id 更改時將新餐廳添加到串列中,因此您必須按餐廳 id 訂購
SELECT r.Id RestaurantId, r.naam, r.email, ...
FROM Restaurant r
LEFT JOIN locatie l ON r.locatieid = l.id
LEFT JOIN tafel t ON r.id = t.restaurantid
ORDER BY r.id
注意,因為餐廳 id 是主鍵,所以不能為空。因此,不要針對 DbNull 對其進行測驗。但是位置和桌子是左連接的,因此可以為空,例如,如果餐廳沒有定義位置或桌子。
每個餐廳的表只能出現一次,因此(restaurantid, Tafelnummer)必須是復合主鍵或具有唯一索引。您還可以有一個單獨的tafelid主鍵,對于整個 tafels 表來說是唯一的。
位置可以按任何順序出現,并且可以分配給多個餐廳。因此,我建議將它們添加到以表號為鍵的字典中。這使我們能夠輕松地查找。
那么邏輯就變成了
List<Restaurant> restaurants = new();
Dictionary<int, Locatie> locations = new();
int restaurantIdOld = -1;
... (skipping details)
while (reader.Read()) {
int restaurantId = (int)reader["RestaurantId"];
if (restaurantId != restaurantIdOld) {
Locatie l = null;
if (reader["LocatieId"] is int locId &&
!locations.TryGetValue(locId, out l))
{
//TODO: get location fields
l = new(locId, postcode, gemeente, straat, huisnummer);
locations.Add(locId, l);
}
//TODO: get restaurant fields
r = new(restaurantId, naam, l, telefoonnummer, email, keuken);
restaurants.Add(r);
}
if (reader["Tafelnummer"] is int tafelnummer) {
//TODO: get table fields
// No need to test whether this is a new table. Tables are unique.
Tafel t = new(restaurantId, tafelnummer, aantalPlaatsen, isBezet);
r.VoegTafelToe(t);
}
}
return restaurants;
我們也可以從 SQL 字串中洗掉 $,因為我們沒有任何字串插值。
無需提前宣告所有變數。在需要的范圍內宣告它們。
我跳過了一些細節。為讀者使用using 宣告。這將在范圍結束時自動關閉它。
using SqlDataReader reader = cmd.ExecuteReader();
您可以對命令和連接執行相同的操作。
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/533143.html
