C# 从数据库表中填充多维数组
Posted
技术标签:
【中文标题】C# 从数据库表中填充多维数组【英文标题】:C# Populate Multidimensional array from database table 【发布时间】:2022-01-11 07:00:25 【问题描述】:我使用 EF Core 为我的博客创建了一个包含 7 列的数据库表,我正在尝试在我的 c# 代码中创建一个多维数组,以便在页面加载时我可以从数据库中检索值,然后将值分配到我的控制器到引导卡中的文本字段。所以 card.1 将有来自数据库中第 1 行的详细信息,卡 .2 将有来自数据库中第 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 = ""
;
但是这会引发 Index out of range 异常:
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]
;
以下是我尝试填充数组以便可以将其返回到我的控制器。 这似乎是出错的地方,它工作正常,但只是将第二个数据库行填充到我的数组中。我将每一列作为一个列表,然后尝试将这些值添加到一个数组中.我可以很好地添加和检索 [0,0] 到 [0,7] 的值,但是一旦我尝试检索 [1,0] [1,1] 等,它就会引发索引超出范围错误。
我整天都在研究这个,发现了很多关于 php 代码或原始 SQL 的信息。还有关于嵌套 for 循环的信息,但我试过了,但无法让它工作。对于本质上填充简单数组的内容来说,这似乎也非常复杂。有人还在 cmets 中建议我研究数据绑定,我确实这样做了。我最终可能需要它来动态更新 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;
尝试在 cmets 中简单地使用下面建议的列表会在返回时引发隐式转换错误:
尝试 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();
我做错了什么? 如何创建一个数组并从我的数据库中填充它,以便随后检索相关值?
【问题讨论】:
抛弃多维数组。 (我假设这是基于 EF 的(对您的问题有用的信息,顺便说一句)并且_context
是 DbContext
。)而不是使用 FirstOrDefault
,请尝试 var myData = _context.ArticlesList.ToList();
并查看 myData
在调试器中
这会为 myData 生成什么类型?它不是 List,因为 List 引发了一个隐式转换错误,即 Generic.ListArticlesList
映射到该表的列表(可能是List<ArticlesList>
- 从您的代码中无法分辨)。不要尝试使用多维数组,使用该列表和 ArticlesList
类型的属性(或该列表的任何通用参数)。使用调试器来解决这个问题——我们不能从这里做到这一点
调用_context.ArticlesList.ToList()
将为您提供查询结果的强类型列表,每行中的字段具有强类型(并正确命名)属性。使用该信息。您可以将数据绑定到该列表。不要通过将其转换为List<object>
来丢失这些信息。找到一些实体框架示例,我已经用尽了我可以通过电话告诉你的内容。
添加了更多细节@AntiqTech
【参考方案1】:
根据对原始答案的评论中的建议,感谢Good Night Nerd Pride,在完成了 EF 教程后,我现在进一步改进了这一点。
在我的控制器中,我只有:
var viewModel = new ArticlesViewModel
//some static variables are assigned in here...
;
viewModel.ListOfArticles = _context.ArticlesList;
在我看来,我正在根据suggested tutorial 动态生成和填充元素。
【讨论】:
【参考方案2】:知道了!结果我需要一个 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 类:
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 的一点帮助。
【讨论】:
恭喜您找到解决问题的方法!但是,我强烈建议您花时间研究实体框架的教程(例如this one)。相信我们,它会在以后为您省去很多麻烦:) 感谢@GoodNightNerdPride,我完成了本教程,并针对上述问题发布了更好的答案。非常感谢。以上是关于C# 从数据库表中填充多维数组的主要内容,如果未能解决你的问题,请参考以下文章