C# 从数据库填充多维数组 table
C# Populate Multidimensional array from database table
我有一个数据库 table,我的博客使用 EF Core 有 7 列,我正在尝试在我的 c# 代码中创建一个多维数组,以便在页面加载时我可以从数据库中检索值然后将我的控制器中的值分配给 bootstrap 卡中的文本字段。因此,card.1 将包含数据库中 Row.1 的详细信息,card.2 将包含数据库中 Row.2 的详细信息等。
这是我的数据库模型:
public class ArticlesList
{
[Key]
public string ArticleReference { get; set; }
public string TitleImageUrl { get; set; }
public string UserId { get; set; }
public string Title { get; set; }
public string Snippet { get; set; }
[DataType(DataType.DateTime)]
[Column(TypeName = "datetime2")]
public DateTime? PostedDateTime { get; set; }
public bool WeeklyNewsList { get; set; }
}
这是我的数据库结构:
我正在尝试按照下面在我的控制器中将数据库中的值分配给我的 ViewModel。但要做到这一点,我需要获取 BOTH 行的数据。
在下面第一次尝试的控制器中,这工作正常,它填充第一张卡没有错误:
string [,] articles = GetArticlesCardDetails.GetCardDetails();
var viewModel = new ArticlesViewModel
{
Article1CardImage = articles[0, 1],
Article1CardTitle = articles[0,3],
Article1CardContent = articles[0, 4],
Article1CardDate = articles[0, 5],
Article2CardTitle = "",
Article2CardContent = "",
Article2CardDate = ""
};
但是这会引发索引超出范围异常:
string [,] articles = GetArticlesCardDetails.GetCardDetails();
var viewModel = new ArticlesViewModel
{
Article1CardImage = articles[0, 1],
Article1CardTitle = articles[0,3],
Article1CardContent = articles[0, 4],
Article1CardDate = articles[0, 5],
Article2CardTitle = articles[1, 3],
Article2CardContent = articles[1, 4],
Article2CardDate = articles[1, 5]
};
下面是我填充数组的尝试,因此它可以 returned 到我的控制器。 这是它似乎出错的地方,它工作正常但只将第二个数据库行填充到我的数组中。我将每一列作为列表获取,然后尝试添加值到一个数组。我可以很好地添加和检索 [0,0] 到 [0,7] 的值,但是一旦我尝试检索 [1,0] [1,1] 等,它就会抛出索引超出范围错误。
我整天都在研究这个,发现了很多关于 php 代码或原始 SQL 的信息。还有关于嵌套 for 循环的信息,但我试过了,但无法让它工作。对于本质上填充简单数组的内容来说,它似乎也非常复杂。有人还在评论中建议我查看数据绑定,我照做了。我最终可能需要它来动态更新 UI,但我现在不需要它。 现在我只需要从几行数据库数据创建一个简单的数组。
尝试 1
public class GetArticlesCardDetails
{
private static readonly ApplicationDbContext _context = new();
public static string[,] GetCardDetails()
{
_context.ChangeTracker.QueryTrackingBehavior = QueryTrackingBehavior.NoTracking;
var articlesEntriesCount = _context.ArticlesList.Count();
Debug.WriteLine("************** articlesEntriesCount: " + articlesEntriesCount.ToString());
_context.ArticlesList.OrderByDescending(x => new { x.PostedDateTime });
var Articles = _context.ArticlesList.FirstOrDefault();
string[,] articles = { };
List<string> referenceList = _context.ArticlesList.Where(c => c.ArticleReference != null).Select(c => c.ArticleReference).ToList();
List<string> titleImageUrlList = _context.ArticlesList.Where(c => c.TitleImageUrl != null).Select(c => c.TitleImageUrl).ToList();
List<string> userIdList = _context.ArticlesList.Where(c => c.UserId != null).Select(c => c.UserId).ToList();
List<string> titleList = _context.ArticlesList.Where(c => c.Title != null).Select(c => c.Title).ToList();
List<string> snippetList = _context.ArticlesList.Where(c => c.Snippet != null).Select(c => c.Snippet).ToList();
List<DateTime> postedList = _context.ArticlesList.Where(c => c.PostedDateTime != null).Select(c => c.PostedDateTime.Value).ToList();
List<bool> weeklyBoolList = _context.ArticlesList.Select(c => c.WeeklyNewsList).ToList();
for (int i = 0; i < articlesEntriesCount; i++)
{
Debug.WriteLine("************** i: " + i.ToString());
articles = new string[,] { { referenceList[i], titleImageUrlList[i], userIdList[i], titleList[i], snippetList[i], postedList[i].ToString(), weeklyBoolList[i].ToString() } };
};
return articles;
}
}
下面是我嵌套 for 循环的尝试:
尝试 2
public class GetArticlesCardDetails
{
private static readonly ApplicationDbContext _context = new();
public static string[,] GetCardDetails()
{
_context.ChangeTracker.QueryTrackingBehavior = QueryTrackingBehavior.NoTracking;
var articlesEntriesCount = _context.ArticlesList.Count();
Debug.WriteLine("************** articlesEntriesCount: " + articlesEntriesCount.ToString());
_context.ArticlesList.OrderByDescending(x => new { x.PostedDateTime });
var Articles = _context.ArticlesList.FirstOrDefault();
string[,] articles = { };
List<string> referenceList = _context.ArticlesList.Where(c => c.ArticleReference != null).Select(c => c.ArticleReference).ToList();
List<string> titleImageUrlList = _context.ArticlesList.Where(c => c.TitleImageUrl != null).Select(c => c.TitleImageUrl).ToList();
List<string> userIdList = _context.ArticlesList.Where(c => c.UserId != null).Select(c => c.UserId).ToList();
List<string> titleList = _context.ArticlesList.Where(c => c.Title != null).Select(c => c.Title).ToList();
List<string> snippetList = _context.ArticlesList.Where(c => c.Snippet != null).Select(c => c.Snippet).ToList();
List<DateTime> postedList = _context.ArticlesList.Where(c => c.PostedDateTime != null).Select(c => c.PostedDateTime.Value).ToList();
List<bool> weeklyBoolList = _context.ArticlesList.Select(c => c.WeeklyNewsList).ToList();
for (int i = 0; i < articlesEntriesCount; i++)
{
for (int j = 0; j < articlesEntriesCount; j++)
{
for (int k = 0; k < articlesEntriesCount; k++)
{
for (int l = 0; l < articlesEntriesCount; l++)
{
for (int m = 0; m < articlesEntriesCount; m++)
{
for (int n = 0; n < articlesEntriesCount; n++)
{
for (int o = 0; o < articlesEntriesCount; o++)
{
Debug.WriteLine("************** i: " + i.ToString());
articles = new string[,] { { referenceList[i], titleImageUrlList[i], userIdList[i], titleList[i], snippetList[i], postedList[i].ToString(), weeklyBoolList[i].ToString() }};
}
}
}
}
}
}
};
return articles;
}
}
尝试另一种尝试简单地使用下面评论中建议的列表会在 return:
上引发隐式转换错误
尝试 3
public class GetArticlesCardDetails
{
private static readonly ApplicationDbContext _context = new();
public static List<object> GetCardDetails()
{
_context.ChangeTracker.QueryTrackingBehavior = QueryTrackingBehavior.NoTracking;
var articlesEntriesCount = _context.ArticlesList.Count();
var articles = _context.ArticlesList.ToList();
return articles;
}
}
在我的控制器中,上面的第三个选项:
List<object> articles = GetArticlesCardDetails.GetCardDetails();
我做错了什么? 我如何创建一个数组并从我的数据库中填充它,然后我才能检索相关值?
知道了!结果我需要一个 DataTable,而不是数组。我正在使用 SQL 查询填充 DataTable,它运行良好。下面是为将来遇到类似问题的其他人准备的:
在我的控制器中:
DataTable articles = _context.DataTable("SELECT * FROM [dbo].[ArticlesList]", new SqlParameter("paramName", SqlDbType.NVarChar) { Value = "a" }
var viewModel = new ArticlesViewModel
{
Article1CardImage = articles.Rows[0].Field<string>(1),
Article1CardTitle = articles.Rows[0].Field<string>(3),
Article1CardContent = articles.Rows[0].Field<string>(4),
Article1CardDate = articles.Rows[0].Field<DateTime>(5).ToString(),
Article2CardTitle = articles.Rows[1].Field<string>(3),
Article2CardContent = articles.Rows[1].Field<string>(4),
Article2CardDate = articles.Rows[1].Field<DateTime>(5).ToString(),
};
还有我的 GetArticlesCardDetails class:
public static class GetArticlesCardDetails
{
public static DataTable DataTable(this ApplicationDbContext _context, string sqlQuery, params DbParameter[] parameters)
{
_context.ChangeTracker.QueryTrackingBehavior = QueryTrackingBehavior.NoTracking;
DataTable dataTable = new DataTable();
DbConnection connection = _context.Database.GetDbConnection();
DbProviderFactory dbFactory = DbProviderFactories.GetFactory(connection);
using (var cmd = dbFactory.CreateCommand())
{
cmd.Connection = connection;
cmd.CommandType = CommandType.Text;
cmd.CommandText = sqlQuery;
if (parameters != null)
{
foreach (var item in parameters)
{
cmd.Parameters.Add(item);
}
}
using (DbDataAdapter adapter = dbFactory.CreateDataAdapter())
{
adapter.SelectCommand = cmd;
adapter.Fill(dataTable);
}
}
//Debug.WriteLine("************** dataTable: " + string.Join(Environment.NewLine, dataTable.Rows.OfType<DataRow>().Select(x => string.Join(" ; ", x.ItemArray))));
return dataTable;
}
}
还有 here 的一点帮助。
根据对原始答案的评论中的建议,并感谢 Good Night Nerd Pride,在完成 EF 教程后,我现在进一步改进了这一点。
在我的控制器中,我只有:
var viewModel = new ArticlesViewModel
{
//some static variables are assigned in here...
};
viewModel.ListOfArticles = _context.ArticlesList;
在我看来,我正在根据 suggested tutorial.
动态生成和填充元素
我有一个数据库 table,我的博客使用 EF Core 有 7 列,我正在尝试在我的 c# 代码中创建一个多维数组,以便在页面加载时我可以从数据库中检索值然后将我的控制器中的值分配给 bootstrap 卡中的文本字段。因此,card.1 将包含数据库中 Row.1 的详细信息,card.2 将包含数据库中 Row.2 的详细信息等。
这是我的数据库模型:
public class ArticlesList
{
[Key]
public string ArticleReference { get; set; }
public string TitleImageUrl { get; set; }
public string UserId { get; set; }
public string Title { get; set; }
public string Snippet { get; set; }
[DataType(DataType.DateTime)]
[Column(TypeName = "datetime2")]
public DateTime? PostedDateTime { get; set; }
public bool WeeklyNewsList { get; set; }
}
这是我的数据库结构:
我正在尝试按照下面在我的控制器中将数据库中的值分配给我的 ViewModel。但要做到这一点,我需要获取 BOTH 行的数据。
在下面第一次尝试的控制器中,这工作正常,它填充第一张卡没有错误:
string [,] articles = GetArticlesCardDetails.GetCardDetails();
var viewModel = new ArticlesViewModel
{
Article1CardImage = articles[0, 1],
Article1CardTitle = articles[0,3],
Article1CardContent = articles[0, 4],
Article1CardDate = articles[0, 5],
Article2CardTitle = "",
Article2CardContent = "",
Article2CardDate = ""
};
但是这会引发索引超出范围异常:
string [,] articles = GetArticlesCardDetails.GetCardDetails();
var viewModel = new ArticlesViewModel
{
Article1CardImage = articles[0, 1],
Article1CardTitle = articles[0,3],
Article1CardContent = articles[0, 4],
Article1CardDate = articles[0, 5],
Article2CardTitle = articles[1, 3],
Article2CardContent = articles[1, 4],
Article2CardDate = articles[1, 5]
};
下面是我填充数组的尝试,因此它可以 returned 到我的控制器。 这是它似乎出错的地方,它工作正常但只将第二个数据库行填充到我的数组中。我将每一列作为列表获取,然后尝试添加值到一个数组。我可以很好地添加和检索 [0,0] 到 [0,7] 的值,但是一旦我尝试检索 [1,0] [1,1] 等,它就会抛出索引超出范围错误。
我整天都在研究这个,发现了很多关于 php 代码或原始 SQL 的信息。还有关于嵌套 for 循环的信息,但我试过了,但无法让它工作。对于本质上填充简单数组的内容来说,它似乎也非常复杂。有人还在评论中建议我查看数据绑定,我照做了。我最终可能需要它来动态更新 UI,但我现在不需要它。 现在我只需要从几行数据库数据创建一个简单的数组。
尝试 1
public class GetArticlesCardDetails
{
private static readonly ApplicationDbContext _context = new();
public static string[,] GetCardDetails()
{
_context.ChangeTracker.QueryTrackingBehavior = QueryTrackingBehavior.NoTracking;
var articlesEntriesCount = _context.ArticlesList.Count();
Debug.WriteLine("************** articlesEntriesCount: " + articlesEntriesCount.ToString());
_context.ArticlesList.OrderByDescending(x => new { x.PostedDateTime });
var Articles = _context.ArticlesList.FirstOrDefault();
string[,] articles = { };
List<string> referenceList = _context.ArticlesList.Where(c => c.ArticleReference != null).Select(c => c.ArticleReference).ToList();
List<string> titleImageUrlList = _context.ArticlesList.Where(c => c.TitleImageUrl != null).Select(c => c.TitleImageUrl).ToList();
List<string> userIdList = _context.ArticlesList.Where(c => c.UserId != null).Select(c => c.UserId).ToList();
List<string> titleList = _context.ArticlesList.Where(c => c.Title != null).Select(c => c.Title).ToList();
List<string> snippetList = _context.ArticlesList.Where(c => c.Snippet != null).Select(c => c.Snippet).ToList();
List<DateTime> postedList = _context.ArticlesList.Where(c => c.PostedDateTime != null).Select(c => c.PostedDateTime.Value).ToList();
List<bool> weeklyBoolList = _context.ArticlesList.Select(c => c.WeeklyNewsList).ToList();
for (int i = 0; i < articlesEntriesCount; i++)
{
Debug.WriteLine("************** i: " + i.ToString());
articles = new string[,] { { referenceList[i], titleImageUrlList[i], userIdList[i], titleList[i], snippetList[i], postedList[i].ToString(), weeklyBoolList[i].ToString() } };
};
return articles;
}
}
下面是我嵌套 for 循环的尝试: 尝试 2
public class GetArticlesCardDetails
{
private static readonly ApplicationDbContext _context = new();
public static string[,] GetCardDetails()
{
_context.ChangeTracker.QueryTrackingBehavior = QueryTrackingBehavior.NoTracking;
var articlesEntriesCount = _context.ArticlesList.Count();
Debug.WriteLine("************** articlesEntriesCount: " + articlesEntriesCount.ToString());
_context.ArticlesList.OrderByDescending(x => new { x.PostedDateTime });
var Articles = _context.ArticlesList.FirstOrDefault();
string[,] articles = { };
List<string> referenceList = _context.ArticlesList.Where(c => c.ArticleReference != null).Select(c => c.ArticleReference).ToList();
List<string> titleImageUrlList = _context.ArticlesList.Where(c => c.TitleImageUrl != null).Select(c => c.TitleImageUrl).ToList();
List<string> userIdList = _context.ArticlesList.Where(c => c.UserId != null).Select(c => c.UserId).ToList();
List<string> titleList = _context.ArticlesList.Where(c => c.Title != null).Select(c => c.Title).ToList();
List<string> snippetList = _context.ArticlesList.Where(c => c.Snippet != null).Select(c => c.Snippet).ToList();
List<DateTime> postedList = _context.ArticlesList.Where(c => c.PostedDateTime != null).Select(c => c.PostedDateTime.Value).ToList();
List<bool> weeklyBoolList = _context.ArticlesList.Select(c => c.WeeklyNewsList).ToList();
for (int i = 0; i < articlesEntriesCount; i++)
{
for (int j = 0; j < articlesEntriesCount; j++)
{
for (int k = 0; k < articlesEntriesCount; k++)
{
for (int l = 0; l < articlesEntriesCount; l++)
{
for (int m = 0; m < articlesEntriesCount; m++)
{
for (int n = 0; n < articlesEntriesCount; n++)
{
for (int o = 0; o < articlesEntriesCount; o++)
{
Debug.WriteLine("************** i: " + i.ToString());
articles = new string[,] { { referenceList[i], titleImageUrlList[i], userIdList[i], titleList[i], snippetList[i], postedList[i].ToString(), weeklyBoolList[i].ToString() }};
}
}
}
}
}
}
};
return articles;
}
}
尝试另一种尝试简单地使用下面评论中建议的列表会在 return:
上引发隐式转换错误尝试 3
public class GetArticlesCardDetails
{
private static readonly ApplicationDbContext _context = new();
public static List<object> GetCardDetails()
{
_context.ChangeTracker.QueryTrackingBehavior = QueryTrackingBehavior.NoTracking;
var articlesEntriesCount = _context.ArticlesList.Count();
var articles = _context.ArticlesList.ToList();
return articles;
}
}
在我的控制器中,上面的第三个选项:
List<object> articles = GetArticlesCardDetails.GetCardDetails();
我做错了什么? 我如何创建一个数组并从我的数据库中填充它,然后我才能检索相关值?
知道了!结果我需要一个 DataTable,而不是数组。我正在使用 SQL 查询填充 DataTable,它运行良好。下面是为将来遇到类似问题的其他人准备的:
在我的控制器中:
DataTable articles = _context.DataTable("SELECT * FROM [dbo].[ArticlesList]", new SqlParameter("paramName", SqlDbType.NVarChar) { Value = "a" }
var viewModel = new ArticlesViewModel
{
Article1CardImage = articles.Rows[0].Field<string>(1),
Article1CardTitle = articles.Rows[0].Field<string>(3),
Article1CardContent = articles.Rows[0].Field<string>(4),
Article1CardDate = articles.Rows[0].Field<DateTime>(5).ToString(),
Article2CardTitle = articles.Rows[1].Field<string>(3),
Article2CardContent = articles.Rows[1].Field<string>(4),
Article2CardDate = articles.Rows[1].Field<DateTime>(5).ToString(),
};
还有我的 GetArticlesCardDetails class:
public static class GetArticlesCardDetails
{
public static DataTable DataTable(this ApplicationDbContext _context, string sqlQuery, params DbParameter[] parameters)
{
_context.ChangeTracker.QueryTrackingBehavior = QueryTrackingBehavior.NoTracking;
DataTable dataTable = new DataTable();
DbConnection connection = _context.Database.GetDbConnection();
DbProviderFactory dbFactory = DbProviderFactories.GetFactory(connection);
using (var cmd = dbFactory.CreateCommand())
{
cmd.Connection = connection;
cmd.CommandType = CommandType.Text;
cmd.CommandText = sqlQuery;
if (parameters != null)
{
foreach (var item in parameters)
{
cmd.Parameters.Add(item);
}
}
using (DbDataAdapter adapter = dbFactory.CreateDataAdapter())
{
adapter.SelectCommand = cmd;
adapter.Fill(dataTable);
}
}
//Debug.WriteLine("************** dataTable: " + string.Join(Environment.NewLine, dataTable.Rows.OfType<DataRow>().Select(x => string.Join(" ; ", x.ItemArray))));
return dataTable;
}
}
还有 here 的一点帮助。
根据对原始答案的评论中的建议,并感谢 Good Night Nerd Pride,在完成 EF 教程后,我现在进一步改进了这一点。
在我的控制器中,我只有:
var viewModel = new ArticlesViewModel
{
//some static variables are assigned in here...
};
viewModel.ListOfArticles = _context.ArticlesList;
在我看来,我正在根据 suggested tutorial.
动态生成和填充元素