MS_ASPNETMVCDataTable - NetDevInfraWGinOSSConsortium/NetDevInfraWiki GitHub Wiki
- æ»ãïŒASP.NET MVCã®å©ç𿹿³ïŒ
ASP.NET MVC ã§ Entity Framework ããã£ã³ã»ã«ããå Žåã®éžæè¢ãšããŠ
ASP.NET MVC + DataTable ãå¿
èŠãªãããæ¬é
ã«ã³ã¬ãçºããã
è£è¶³ïŒãã®éžæã®èæ¯ïŒ: ãEntity Framework ã
ãã£ã³ã»ã«ããå Žåããšããåæãæ¬ããŒãžã®åºçºç¹ã§ããã
ãã®å€æçç±ã¯ Entity Framework ã®æžå¿µ ã
ADO.NET vs ORM ã§è«ããããŠããããORM ãæ¡ããªãå Žåã®ããŒã¿è¡šçŸã®éžæè¢ã â DataTable / DataSet ⊠åãªããååã¯æåå â æ¬ããŒãž â¡ POCOïŒèªåã®ã¯ã©ã¹ïŒ ⊠åããããããã³ã°ãèªåã§æžã ⢠dynamic / ExpandoObject ⊠åãªããåç ⣠Dapper çã®è»œéããã㌠⊠åãããSQL ã¯èªåã§æžã â çŸåšã®äž»æµçŸåšãªã â£ïŒDapper çïŒã第äžã«æ€èšããã
// DapperïŒSQL ã¯èªåã§æžããçµæã¯ POCO ã§åãã var products = conn.Query<Product>( "SELECT Id, Name, Price FROM Products WHERE CategoryId = @cid", new { cid = 3 }).ToList();ãEF ã¯éãããDataTable ã¯åããªããŠèŸãããšãã
åœæã®ãžã¬ã³ãã¯ã軜éããããŒãåããââãšããã®ã
ãã®åŸã®æµãã§ããããã ããæ¢åã® ADO.NET è³ç£ïŒDataTable ãè¿ãå ±éåºç€ïŒã
ããå Žåã¯ãæ¬ããŒãžã®å 容ãä»ãå¿ èŠã«ãªãã
-
c# - Displaying standard DataTables in MVC - Stack Overflow
https://stackoverflow.com/questions/2243898/displaying-standard-datatables-in-mvc-
ASP.NET MVC ã§ DataTable ã®äœµçšã¯åé¡ãªãã
There is nothing about MVC that prevents you from using ADO.NET. -
以äžã¯ã
- ãASP.NET MVC ã§ DataTable ã䜿çšããã®ããã¹ããã©ã¯ãã£ã¹ã§ã¯ç¡ããã
ãšèšã£ãŠããã®ã§ã¯ç¡ããŠã - ãController ã§ããŒã¿ãäœæããã®ããã¹ããã©ã¯ãã£ã¹ã§ã¯ç¡ããããšèšã£ãŠããã®ã§ã
ãééããªãããã
Now, I'm violating a whole lot of principles and "best-practices" of ASP.NET MVC here, so please understand this is just a simple demonstration. - ãASP.NET MVC ã§ DataTable ã䜿çšããã®ããã¹ããã©ã¯ãã£ã¹ã§ã¯ç¡ããã
-
è£è¶³ïŒåæã®èªè§£ã¯æ£ããïŒ: åŒçšå ã®è±æã
ãDataTable ãæªããã§ã¯ãªããController ã«ããŒã¿çæãæžãã®ãæªãã
ãšèªã¿åã£ãŠããç¹ã¯ãæ£ç¢ºã§ãããMVC ã®è²¬ååæ :
ãControllerã ãªã¯ãšã¹ããåããããµãŒãã¹å±€ãåŒã³ããView ãéžã¶ â ããŒã¿ååŸããžãã¯ãã®ãã®ã¯æžããªã ãModelã ããŒã¿ãšããžãã¹ ããžã㯠â ããã§ DataTable ãè¿ããŠããMVC ã®ååã«ã¯åããªã ãViewã 衚瀺ã ãDataTable ã䜿ãããšã®å®éã®æ¬ ç¹ã¯ãMVC ã®ååãšã¯å¥ã®è©±ã§ããã
æ¬ ç¹ å 容 ã³ã³ãã€ã«æã«æ€èšŒãããªã row["Nmae"]ã®æã¡ééããå®è¡æãŸã§åãããªã âãªãã¡ã¯ã¿ãªã³ã°ãå¹ããªã ååã®å€æŽã IDE ã远跡ã§ããªã ã¡ã¢ãªãé£ã 倿Žè¿œè·¡ã»ã¹ããŒãæ å ±ãæã€ãããPOCO ã®æ°å åäœãã¹ããæžãã«ãã ãã¹ã ããŒã¿ã®æ§ç¯ãåé· View ãèªã¿ã«ãã @item["Name"]ã䞊ã¶äžæ¹ãDataTable ãæå©ãªå Žé¢ãããã
ã»ãåãåçã«æ±ºãŸããïŒåž³ç¥šãCSV ãšã¯ã¹ããŒããæ±çšæ€çŽ¢ç»é¢ïŒ ã»ã¹ããŒããå®è¡æãŸã§åãããªã ã»æ¢åã®å ±éåºç€ã DataTable ãåæã«ããŠãã ã»Excel åºåïŒClosedXML ç㯠DataTable ãçŽæ¥åããããïŒ
åäžã¬ã³ãŒãã®åŠçãè¡ãå Žåç㯠POCO ã® ViewModel ãäœæããã
è£è¶³ïŒãã®æ¹éã¯çŸåšãæ£ããïŒ: ã衚瀺㯠DataTableã
å ¥å㯠POCO ã® ViewModelããšãã䜿ãåãã¯ã
å®åçãªæè¡·æ¡ãšããŠåŠ¥åœã§ãããããªã DataTable ã§ã¯åæ¹åãã€ã³ãã£ã³ã°ã§ããªãã®ãã ModelBinder ã¯ãããããã£åãã§ãã©ãŒã ã®å€ã察å¿ä»ãã <input name="Name" value="âŠ"> â model.Name DataTable ã¯åããã€ã³ãã¯ãµãã§æã€ row["Name"] â ããããã£ã§ã¯ãªã â ModelBinder ã察å¿ä»ããããªã ãŸããDataRow ã® public ããããã£ã¯ RowError / HasErrors / Table / ItemArray / RowState â ãæ¥åããŒã¿ãšã¯ç¡é¢ä¿ãªãã®ã°ãããâ ïŒåŸè¿°ã® WebGrid ã®åé¡ãšåãæ ¹ïŒ// å ¥åç»é¢çšã® ViewModelïŒPOCOïŒ public class ProductEditViewModel { public int Id { get; set; } [Required(ErrorMessage = "ååã¯å¿ é ã§ã")] [StringLength(50)] public string Name { get; set; } [Range(0, 999999)] public decimal Price { get; set; } }POCO ã«ãããšã以äžãåæã«æã«å ¥ãã
ã»åæ¹åãã€ã³ãã£ã³ã°ïŒ[HttpPost] ã®ã¡ãœããåŒæ°ã§åãåããïŒ ã»ããŒã¿æ³šéã«ãããå ¥åæ€èšŒãïŒãµãŒãã»ã¯ã©ã€ã¢ã³ãäž¡æ¹ïŒ ã»IntelliSense ãš ã³ã³ãã€ã«æãã§ã㯠ã»åäœãã¹ãã®å®¹æãäžèŠ§ã¯ DataTableãæçŽ°ã¯ POCO ãšããæ··åšã¯ã
ç§»è¡éäžã®æ§æãšããŠçŸå®çã§ããã
foreach ã§åŠçå¯èœã
è£è¶³ïŒçŸåšã¯ããã第äžéžæïŒ:
WebGridãå»ããçŸåšã
foreachã§æžãã®ãæã確å®ã§ãã
ïŒASP.NET MVCã®WebGridïŒã@model System.Data.DataTable <table class="table"> <thead> <tr> @foreach (System.Data.DataColumn col in Model.Columns) { <th>@col.ColumnName</th> } </tr> </thead> <tbody> @foreach (System.Data.DataRow row in Model.Rows) { <tr> @foreach (System.Data.DataColumn col in Model.Columns) { <td>@row[col]</td> } </tr> } </tbody> </table>åãåçãªç»é¢ïŒæ±çšæ€çŽ¢ãªã©ïŒã§ã¯ã
ããã DataTable ã®æ¹ãçŽ çŽã«æžããââãšããå©ç¹ã
ããã§å¹ããŠãããRazor ã®
@ã¯èªåçã« HTML ãšã¹ã±ãŒããããããã
XSS ã®å¿é ã¯èŠããªãïŒãšã³ã³ãŒãã£ã³ã°ïŒã
@Html.Raw()ã䜿ããªãéãå®å šã§ããã
WebGrid ã®ã³ã³ã¹ãã©ã¯ã¿ã®ç¬¬äžåŒæ°ã®
source ã¯ãIEnumerable ããµããŒãããå¿
èŠãããã®ã§ã
DataTable äœ¿çšæã¯ãåã®å€æãå¿
èŠãã«ãªããããã
以äžã§ IEnumerable<DataRow> ã«å€æå¯èœã
var result = dt.AsEnumerable();ãããããã® result ã¯ã
@{
ã»ã»ã»
var grid = new WebGrid(erc);
ã»ã»ã»
}
ã»ã»ã»
@grid.GetHtml()
ã»ã»ã»ãšããŠäœ¿çšã§ããªãã
çç±ã¯ã
DataRow ã® public property ãã
- RowError property
- HasError property
ã§ããããã®ãããã
詳ããã¯ãäžèšãåç §ã®ããšã
- DataTableExtensions.AsEnumerable ã¡ãœãã (DataTable) (System.Data)
https://learn.microsoft.com/ja-jp/dotnet/api/system.data.datatableextensions.asenumerable - WebGrid and DataTable | The ASP.NET Forums
https://forums.asp.net/t/1673391.aspx?WebGrid%20and%20DataTable
ãã®å Žåã
-
åŸè¿°ã®ããã«ãDataTable ããList<dynamic> ã«å€æãããã
-
grid.Column() ã¡ãœããã§ä»¥äžã®ããã«ãformat ãæç€ºããã
grid.Column("Name", format: (item) => item.Value["Name"].ToString()),
-
ãªããããã§ HTML ãã«ããŒã䜿çšããã«ã¯ã以äžã®ããã«åŠçããã
- asp.net mvc 3 - how to format html helpers in webgrid column - Stack Overflow
https://stackoverflow.com/questions/15158183/how-to-format-html-helpers-in-webgrid-column
format: item => Html.TextBox((item) => item.Value["Name"].ToString())
- asp.net mvc 3 - how to format html helpers in webgrid column - Stack Overflow
-
ãšãã€ã€æãã«åŠçã§ãããããã
è£è¶³ïŒåå ã®èª¬æãæ£ç¢ºã«ããŠããïŒ: åæã®ãDataRow ã®
public property ã RowError / HasError ã§ããããããšãã蚺æã¯
æ£ããæ¹åã ããå°ãè£è¶³ãããšåãããããããWebGrid ãåãæ±ºããä»çµã¿ã columns ãæå®ããªãå Žåã source ã®èŠçŽ ã®åãããªãã¬ã¯ã·ã§ã³ã§èª¿ã¹ãã ãã®ãpublic ããããã£ããåã«ãã ãDataRow ã® public ããããã£ã ã»ItemArray ã»HasErrors â åæã®ãHasErrorãã¯æ£ãã㯠HasErrors ã»RowError ã»RowState ã»Table â ãæ¥åããŒã¿ã®å㯠1 ã€ãåºãŠããªããâ row["Name"] ã¯ããããã£ã§ã¯ãªãã€ã³ãã¯ãµã®ããã ãªãã¬ã¯ã·ã§ã³ããã¯ãåããšããŠèŠããªãç§»è¡ã¡ã¢: åæã®ãHasError propertyãã¯ã
æ£ããã¯HasErrorsïŒè€æ°åœ¢ïŒã§ãããåæãæãã 2 ã€ã®åé¿çã¯ãã©ã¡ããæå¹ã§ããã
æ¹æ³ æ§è³ª List<dynamic>ã«å€æåãåçã§ãåãããã ãé ãïŒåŸè¿°ïŒ format:ãæç€ºå€æãäžèŠã§éãããã ãåãå ã«ç¥ã£ãŠããå¿ èŠããã åãåºå®ãªã
format:æç€ºã®æ¹ãè¯ãã
倿ã®ã³ã¹ããã¡ã¢ãªãå¢ããªãããã§ããã
List<dynamic> ã«ã(IDictionary<string, object>) ExpandoObject ã远å ããŠããã
var result = new List<dynamic>();
foreach (DataRow row in table.Rows)
{
var obj = (IDictionary<string, object>)new ExpandoObject();
foreach (DataColumn col in table.Columns)
{
obj.Add(col.ColumnName, row[col.ColumnName]);
}
result.Add(obj);
}è£è¶³ïŒãã®æ¹æ³ã®æ§èœäžã®æ³šæïŒ: åæã®åèãªã³ã¯ã«ã
ãexceedingly slowããšãã Stack Overflow ã®æçš¿ãæãã£ãŠããéãã
ãã®å€æã¯é ããçç±ãæç¢ºã«ããŠããããé ãçç±ã â ExpandoObject ã¯å éšã§èŸæžãæã€ â è¡æ° Ã åæ° ã®åã ãèŸæžãšã³ããªãäœã â¡ dynamic ã®ã¢ã¯ã»ã¹ã¯ãå®è¡æãã€ã³ãã£ã³ã°ã â åŒã³åºãããšã« DLR ãã¡ã³ãã解決ããïŒãã£ãã·ã¥ã¯ãããéãïŒ â¢ WebGrid ãåãæ±ºããéãã1 è¡ç®ããªãã¬ã¯ã·ã§ã³ã§èª¿ã¹ãã ⣠ãœãŒãã»ããŒãžã³ã°ã dynamic çµç±ã§è¡ããã â 1,000 è¡çšåºŠã§ãäœæã§ããé ãã«ãªãæ§èœãåªå ãããªã:
// â 衚瀺ããåã ãã POCO ã«è©°ãæ¿ããïŒæãéãïŒ var rows = table.AsEnumerable() .Select(r => new ProductRow { Id = r.Field<int>("Id"), Name = r.Field<string>("Name") }) .ToList(); // â¡ ããŒãžã³ã°ã DB åŽã§è¡ãïŒããããå šä»¶æã£ãŠããªãïŒ // SELECT ... ORDER BY Id OFFSET @skip ROWS FETCH NEXT @take ROWS ONLYâ¡ ãæ¬è³ªçãªå¯Ÿçã§ããã
1 äžä»¶ãåã£ãŠããŠç»é¢ã§ 20 件衚瀺ãããšããèšèšèªäœãåé¡ã§ã
DB åŽã§ããŒãžã³ã°ããã®ãæ£ãã
ïŒSQL ServerïŒã
row.Field<T>()ã䜿ãå©ç¹:(int)row["Id"] // â DBNull ã§ InvalidCastException row.Field<int?>("Id") // â DBNull ã null ãšããŠæ±ãã â
åé€ããªããšã¡ã¢ãªãé£ãã
Hiddenã«æ ŒçŽããŠããã
Hidden ã«ãã€ããªã»ã·ãªã¢ã©ã€ãºãã DataTable ã® Base64 ãšã³ã³ãŒãã£ã³ã°ãä¿åã
ãªãŒããŒããããããã
ç§»è¡ã¡ã¢ïŒåæã®èŠåºãã®èª€åïŒ: åæã¯ãHidennã«æ ŒçŽããŠããããš
ãªã£ãŠããããããHiddenãã«ä¿®æ£ããã
è£è¶³ïŒ3 ã€ã®éžæè¢ã®è©äŸ¡ãšãçŸåšã®æšå¥šïŒ: 3 ã€ãšãå®åšããææ³ã ãã
çŸåšã¯è©äŸ¡ã倧ããå€ãã£ãŠããã
æ¹æ³ åœæã®è©äŸ¡ çŸåšã®è©äŸ¡ Session ã«æ ŒçŽ ã¡ã¢ãªãé£ã ã¹ã±ãŒã«ã¢ãŠãã§åé¡ã忣ãã£ãã·ã¥ãªãå¯ Hidden ã«ã·ãªã¢ã©ã€ãº ãµã€ãºãå¢ãã 䜿ã£ãŠã¯ãªããªã â ïŒåŸè¿°ïŒ éœåºŠ DB ããååŸ ãªãŒããŒããã ãããæ£è§£ãDB åŽããŒãžã³ã°ãšäœµçš â¡ Hidden ãžã®æ ŒçŽã¯ãçŸåšã¯æç¢ºã«éæšå¥šã§ããã
ãåé¡ç¹ã â ãã»ãã¥ãªãã£ã å©çšè ã«æ¹ç«ããã â Base64 ãæ»ãã°äžèº«ãèªããïŒ[ãšã³ã³ãŒãã£ã³ã°] åç §ïŒ â æ¹ç«ãããããŒã¿ããã®ãŸãŸä¿¡ãããšé倧ãªèåŒ±æ§ â¡ ãBinaryFormatter ã .NET 5 以éã§ç¡å¹åããããâ â DataTable ã®ãã€ã㪠ã·ãªã¢ã©ã€ãºã¯æ¢å®ã§äœ¿ããªã â æ¢ç¥ã®è匱æ§ïŒä»»æã³ãŒãå®è¡ïŒã®ãã ⢠ããŒãž ãµã€ãºãè¥å€§ããïŒ[ASP.NET ViewState] ãšåãåé¡ïŒ
BinaryFormatter㯠.NET 9 ã§å®å šã«åé€ãããã
DataTable.ReadXml/WriteXmlã¯äœ¿ãããã
ãããã Hidden ã«æ¥åããŒã¿ãèŒããªãã®ãæ£ãããâ Session ã®çŸåšã®æ±ã:
ã»ã€ã³ããã»ã¹ Session ã¯ãã¹ã±ãŒã«ã¢ãŠãã§ããªãã â è€æ°ãµãŒãã«åæ£ãããšãå¥ãµãŒãã«é£ãã æã«å€±ããã ã»åæ£ãã£ãã·ã¥ïŒRedis / SQL ServerïŒã«çœ®ãã°å ±æã§ãããã 倧ã㪠DataTable ã眮ããšãã·ãªã¢ã©ã€ãºã®ã³ã¹ããæ¯é çãã«ãªã â [ASP.NET Coreã®Sessionå©ç𿹿³] / [忣ãã£ãã·ã¥] åç §â¢ éœåºŠ DB ããååŸãæ£è§£ã§ããçç±:
ã»ç¶æ ãæããªãïŒã¹ããŒãã¬ã¹ïŒïŒãæ°Žå¹³ã«ã¹ã±ãŒã«ããã ã»ããŒã¿ãåžžã«ææ° ã»ããªãŒããŒããããã¯ããDB åŽã§ããŒãžã³ã°ããã°å°ããã â 20 ä»¶ã ãåãã°ãåŸåŸ© 1 åã§æ° ms â å šä»¶ã Session ã«èŒããæ¹ãããã»ã©é«ãã€ãçŸåšã®å®è£ ã®åœ¢:
// æ€çŽ¢æ¡ä»¶ã ããæã¡åãïŒURL ã®ã¯ãšãªæååïŒ // /products?keyword=abc&page=3&sort=price public IActionResult Index(string keyword, int page = 1, string sort = "id") { var (rows, total) = _repository.Search(keyword, page, pageSize: 20, sort); return View(new ProductListViewModel { Rows = rows, Total = total, Page = page }); }æ¡ä»¶ã URL ã«æããããšã
ã»ããã¯ããŒã¯ã§ãããå ±æã§ãã ã»æ»ããã¿ã³ãæ£ããåã ã»ãµãŒãã«ç¶æ ãæããªããšãã坿¬¡çãªå©ç¹ãåŸãããã
- MVC Web Grid using Dynamic Data Table
https://www.c-sharpcorner.com/code/2910/mvc-web-grid-using-dynamic-data-table.aspx
- c# - Displaying standard DataTables in MVC
https://stackoverflow.com/questions/2243898/displaying-standard-datatables-in-mvc - asp.net mvc 3 - Populate MVC Webgrid from DataTable
https://stackoverflow.com/questions/6168548/populate-mvc-webgrid-from-datatable - asp.net mvc 3 webgrid bound to List<dynamic> is exceedingly slow
https://stackoverflow.com/questions/17322239/asp-net-mvc-3-webgrid-bound-to-listdynamic-is-exceedingly-slow
- DataTableExtensions.AsEnumerable ã¡ãœãã
https://learn.microsoft.com/ja-jp/dotnet/api/system.data.datatableextensions.asenumerable - DataRowExtensions.Field<T> ã¡ãœãã
https://learn.microsoft.com/ja-jp/dotnet/api/system.data.datarowextensions.field - BinaryFormatter ã®ã·ãªã¢ã«åã¡ãœããã¯äºææ§ããããŸããïŒ.NET 9 ã§åé€ïŒ
https://learn.microsoft.com/ja-jp/dotnet/core/compatibility/serialization/9.0/binaryformatter-removed
Tags: ç§»è¡, .NETéçº, ASP.NET, ASP.NET MVC, ADO.NET