ASP.NET MVC画面イメージをPDFにする。
ASP.NET MVCの画面をPDF化する方法
ASP.NET MVCでの帳票関連で使えるのがないか調べている内に見つかった。もので、画面イメージをそのままPDF化出来るものがあったので、メモる。
TuesPechkin
wkhtmltopdfをベースにラッピングしている模様。注意としてwkhtmltopdfがAzureでは動作しないみたいで、Azureで使用するなら別の方法を考えた方がいいかも GitHub - tuespetre/TuesPechkin: A .NET wrapper for the wkhtmltopdf library with an object-oriented API.
Nuget
Nugetからインストールする。Win32と64がそれぞれあるけど、AnyCPUで問題なかった。
PM> Install-Package TuesPechkin.Wkhtmltox.AnyCPU
Controller
pdf化したい画面をUrlにし、HtmlToPdfDocumentに渡せば基本簡単に出来ちゃう感じです。 ASP.NET MVCでやっているが、MVCは特に関係なさそう。
using TuesPechkin; public class HomeController : Controller { public ActionResult ToPdfPage() { var helper = new UrlHelper(ControllerContext.RequestContext); var indexUrl = helper.Action("Index", "Home", null, Request.Url.Scheme); var document = new HtmlToPdfDocument() { GlobalSettings = { ProduceOutline = true, DocumentTitle = "PDF Sample", PaperSize = PaperKind.A4, Margins = { All = 1.375, Unit = Unit.Centimeters } }, Objects = { new ObjectSettings() { PageUrl = indexUrl, }, } }; var converter = new StandardConverter( new PdfToolset( new WinAnyCPUEmbeddedDeployment( new TempFolderDeployment()))); var pdfData = converter.Convert(document); return File(pdfData, "application/pdf", "PdfSample.pdf"); } }
ExcelファイルをPdfに変換する。
前提条件
Visual Studioでプロジェクトを生成し、参照を追加
Nugetで以下のパッケージを追加します。 * Microsoft.Office.Interop.Excel
using
オープンするオブジェクトはすべて「ComObject」になるらしく、いちいち開放してあげないとプロセスが残ってしまう。
using Microsoft.Office.Interop.Excel; // Excel関連 using System.Runtime.InteropServices; // ComObjectを開放するため
ExcelファイルのOpen
private Application _application = new Application(); private Workbook _workbook; _application.Visible = false; // Excel Window 非表示 _workbook = (Workbook)_application.Workbooks.Open(filepath);
ExcelをPdf出力する
そなえつけの「ExportAsFixedFormat」関数でExcelのPdf出力は簡単に出来た。
_workbook.Worksheets.Select(); // 全シート選択状態 _workbook.ExportAsFixedFormat( XlFixedFormatType.xlTypePDF, //XPSとPDFのどれか pdfFilePath, //PDFファイルの出力パス XlFixedFormatQuality.xlQualityStandard); //品質:StandardとMinimumのみ
ComObjectの開放
面倒だったのが、SheetもCellもつくたびComObjectの参照カウントが増えるため、任意に解除する必要があった。
public void SetWorkSheet(int sheetNo) { Marshal.ReleaseComObject(_worksheet); _worksheet = _workbook.Worksheets.Item[sheetNo]; } public string GetCellText(int rowNo, int colNo) { string ret; var cell = _worksheet.Cells[rowNo, colNo]; ret = cell.Text; Marshal.ReleaseComObject(cell); return ret; } public void Close() { if (_worksheet != null) { Marshal.ReleaseComObject(_worksheet); _worksheet = null; } if (_workbook != null) { _workbook.Close(false); // 変更分を保存せず終了する。 Marshal.ReleaseComObject(_workbook); _workbook = null; } if (_application != null) { _application.Quit(); Marshal.ReleaseComObject(_application); _application = null; } }
作ったソースの中から、一部メモとして残す。
最終的に
ComObject開放がうまくいかなかったり、プロセスが残ったりしたので、Excelの操作系はClosedXMLを利用することにした。
ASP.NET MVC AD認証ログイン
注意
このポストはまだ成功確認が取れていない状態のメモです。 環境が整い次第テストを行う予定で、そのときのための準備になります。
AD認証でのログインについて調べる
Visual StudioのテンプレートではUseOpenIdConnectAuthenticationにより、OpenIdを利用したADログインになるため、 やりたいことの参考が出来なかったため、調べた事をメモする。
MVC Web ApplicationをMVCで認証なしで作成する。
プロジェクトにNugetから追加する。
参照にPrincipalContextを使うためのライブラリを追加
- System.DirectoryServices
- System.DirectoryServices.AccountManagement
User
IUserを継承したユーザを作成する。 ただし、生成にはUserPrincpalから取得するようにする。
using Microsoft.AspNet.Identity; using System.DirectoryServices.AccountManagement; using System.Threading.Tasks; public class AppUser : IUser<string> { private UserPrincipal _adUser; public AppUser(UserPrincipal adUser) { this._adUser = adUser; } public async Task<ClaimsIdentity> GenerateUserIdentityAsync(UserManager<AppUser> manager) { var userIdentity = await manager.CreateIdentityAsync(this, DefaultAuthenticationTypes.ApplicationCookie); return userIdentity; } #region IUser<string> Members public string Id => _adUser.SamAccountName; public string UserName { get => _adUser.SamAccountName; set { throw new System.NotImplementedException(); } } #endregion }
UserStore
ユーザ関連のCLUD処理を行うStoreクラスを定義する。 PrincipalContextからFindByIdentityにより、ユーザの取得を行う。
using Microsoft.AspNet.Identity; using System.DirectoryServices.AccountManagement; using System.Threading.Tasks; public class AppUserStore : IUserStore<AppUser>, IUserStore<AppUser, string> { private readonly PrincipalContext _context; private AppUserStore(PrincipalContext context) { _context = context; } // context.Get<PrincipalContext>()でADのcontextを取得 public static AppUserStore Create(IdentityFactoryOptions<AppUserStore> options, IOwinContext context) { // PrincipalContextをOwinContextから取得するようにする。StartUpでCreatePerOwinContextに追加しておく //var principalContext = new PrincipalContext(ContextType.Domain); var principalContext = context.Get<PrincipalContext>(); return new AppUserStore(principalContext); } #region IUserStore<MyUser, string> Members public Task CreateAsync(AppUser user) { throw new NotImplementedException(); } public Task DeleteAsync(AppUser user) { throw new NotImplementedException(); } public void Dispose() { throw new NotImplementedException(); } // UserPrincipal.FindByIdentityにより、検索する public Task<AppUser> FindByIdAsync(string userId) { var user = UserPrincipal.n(_context, userId); return Task.FromResult<AppUser>(new AppUser(user)); } public Task<AppUser> FindByNameAsync(string userName) { var user = UserPrincipal.FindByIdentity(_context, userName); return Task.FromResult<AppUser>(new AppUser(user)); } public Task UpdateAsync(AppUser user) { throw new NotImplementedException(); } #endregion }
UserMananger
UserStoreクラスの総裁を行うクラス
using Microsoft.AspNet.Identity; using System.DirectoryServices.AccountManagement; using System.Threading.Tasks; public class AppUserMananger : UserManager<AppUser> { private readonly PrincipalContext _context; private AppUserMananger(IUserStore<AppUser> store, PrincipalContext context) : base(store) { _context = context; } public static AppUserMananger Create(IdentityFactoryOptions<AppUserMananger> options, IOwinContext context) { var userStore = context.Get<AppUserStore>(); var principalContext = context.Get<PrincipalContext>(); return new AppUserMananger(userStore, principalContext); } public override async Task<bool> CheckPasswordAsync(AppUser user, string password) { return await Task.FromResult(_context.ValidateCredentials(user.UserName, password, ContextOptions.Negotiate)); } }
SignInManager
ログイン状態を管理するクラス
using Microsoft.AspNet.Identity; using System.DirectoryServices.AccountManagement; using System.Threading.Tasks; public class AppSignInManager : SignInManager<AppUser, string> { UserManager<AppUser, string> _manager; private AppSignInManager(UserManager<AppUser, string> userManager, IAuthenticationManager authenticationManager) : base(userManager, authenticationManager) { _manager = UserManager; } public static AppSignInManager Create(IdentityFactoryOptions<AppSignInManager> options, IOwinContext context) { // UserManagerはOwinContextから取得する。 AppUserMananger manager = context.GetUserManager<AppUserMananger>(); return new AppSignInManager(manager, context.Authentication); } public override Task<ClaimsIdentity> CreateUserIdentityAsync(AppUser user) { return user.GenerateUserIdentityAsync((AppUserMananger)UserManager); } public override async Task<SignInStatus> PasswordSignInAsync(string userName, string password, bool isPersistent, bool shouldLockout) { var result = SignInStatus.Failure; try { var user = await this.UserManager.FindAsync(userName, password); if (user != null) { await this.SignInAsync(user, isPersistent, true); result = SignInStatus.Success; } } catch { result = SignInStatus.Failure; } return result; } }
StartUp
using Owin; using Microsoft.Owin.Security; using Microsoft.Owin.Security.Cookies; using Microsoft.AspNet.Identity; using System.Threading.Tasks; using Microsoft.AspNet.Identity.Owin; using Microsoft.Owin; using System.DirectoryServices.AccountManagement; using System.Security.Claims; [assembly: OwinStartup(typeof(MvcWeb.OwinStartUp))] public class OwinStartUp { public void Configuration(IAppBuilder app) { app.CreatePerOwinContext(() => new PrincipalContext(ContextType.Domain)); app.CreatePerOwinContext<AppUserMananger>(AppUserMananger.Create); app.CreatePerOwinContext<AppSignInManager>(AppSignInManager.Create); app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType); app.UseCookieAuthentication(new CookieAuthenticationOptions() { AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie, LoginPath = new PathString("/Account/Login"), Provider = new CookieAuthenticationProvider { OnValidateIdentity = SecurityStampValidator.OnValidateIdentity<AppUserMananger, AppUser>( validateInterval: TimeSpan.FromMinutes(30), regenerateIdentity: (manager,user) => user.GenerateUserIdentityAsync(manager)) } }); } }
LoginViewModel
public class LoginViewModel { [Required] [Display(Name = "ユーザID")] public string UserID { get; set; } [Required] [DataType(DataType.Password)] [Display(Name = "パスワード")] public string Password { get; set; } [Display(Name = "このアカウントを記憶する")] public bool RememberMe { get; set; } }
AccountController
http://localhost/Acount/LoginからADのユーザ名、パスワードでログインする処理
[Authorize] public class AccountController : Controller { // // GET: /Account/Login [AllowAnonymous] public ActionResult Login(string returnUrl) { ViewBag.ReturnUrl = returnUrl; return View(); } // // POST: /Account/Login [HttpPost] [AllowAnonymous] public async Task<ActionResult> Login(LoginViewModel model, string returnUrl) { if (!ModelState.IsValid) { return View(model); } AppSignInManager signInManager = HttpContext.GetOwinContext().Get<AppSignInManager>(); AppUserMananger userManager = HttpContext.GetOwinContext().GetUserManager<AppUserMananger>(); // これは、アカウント ロックアウトの基準となるログイン失敗回数を数えません。 // パスワード入力失敗回数に基づいてアカウントがロックアウトされるように設定するには、shouldLockout: true に変更してください。 var result = await signInManager.PasswordSignInAsync(model.UserID, model.Password, model.RememberMe, shouldLockout: false); switch (result) { case SignInStatus.Success: return RedirectToLocal(returnUrl); case SignInStatus.LockedOut: return View("Lockout"); case SignInStatus.RequiresVerification: return RedirectToAction("SendCode", new { ReturnUrl = returnUrl, RememberMe = model.RememberMe }); case SignInStatus.Failure: default: ModelState.AddModelError("", "無効なログイン試行です。"); return View(model); } } private ActionResult RedirectToLocal(string returnUrl) { if (Url.IsLocalUrl(returnUrl)) { return Redirect(returnUrl); } return RedirectToAction("Index", "Home"); } }
Login View
@using MvcWeb.Models @model LoginViewModel @{ ViewBag.Title = "ログイン"; } <h2>@ViewBag.Title.</h2> <div class="row"> <div class="col-md-8"> <section id="loginForm"> @using (Html.BeginForm("Login", "Account", new { ReturnUrl = ViewBag.ReturnUrl }, FormMethod.Post, new { @class = "form-horizontal", role = "form" })) { @Html.AntiForgeryToken() <h4>ローカル アカウントを使用してログインします。</h4> <hr /> @Html.ValidationSummary(true, "", new { @class = "text-danger" }) <div class="form-group"> @Html.LabelFor(m => m.UserID, new { @class = "col-md-2 control-label" }) <div class="col-md-10"> @Html.TextBoxFor(m => m.UserID, new { @class = "form-control" }) @Html.ValidationMessageFor(m => m.UserID, "", new { @class = "text-danger" }) </div> </div> <div class="form-group"> @Html.LabelFor(m => m.Password, new { @class = "col-md-2 control-label" }) <div class="col-md-10"> @Html.PasswordFor(m => m.Password, new { @class = "form-control" }) @Html.ValidationMessageFor(m => m.Password, "", new { @class = "text-danger" }) </div> </div> <div class="form-group"> <div class="col-md-offset-2 col-md-10"> <div class="checkbox"> @Html.CheckBoxFor(m => m.RememberMe) @Html.LabelFor(m => m.RememberMe) </div> </div> </div> <div class="form-group"> <div class="col-md-offset-2 col-md-10"> <input type="submit" value="ログイン" class="btn btn-default" /> </div> </div> <p> @Html.ActionLink("新しいユーザーとして登録する", "Register") </p> @* これを有効にする前に、パスワード リセット機能に対するアカウント確認を有効にしてください。 <p> @Html.ActionLink("パスワードを忘れた場合", "ForgotPassword") </p>*@ } </section> </div> <div class="col-md-4"> <section id="socialLoginForm"> @Html.Partial("_ExternalLoginsListPartial", new ExternalLoginListViewModel { ReturnUrl = ViewBag.ReturnUrl }) </section> </div> </div> @section Scripts { @Scripts.Render("~/bundles/jqueryval") }
ASP.Net MVC Identity 認証
ASP.NET MVC プロジェクトを作成
認証を選択するとデフォルトの認証ロジックが貼るため、認証なしで作成する。
プロジェクトにNugetから追加する。
AppUser
UserNameとPasswordのみの簡単なものにします。 適当なフォルダーに作成します。
public class AppUser : IUser<string> { public string Id { get; set; } = Guid.NewGuid().ToString(); public string UserName { get; set; } public string Password { get; set; } }
UserManager
UserStoreクラスを制御するラッピングクラス
Create(IdentityFactoryOptions, IOwinContext)を実装して、インスタンス生成時に呼ばれる様にしている。 現状としてはどんな仕組みで呼び出し時にCreateでパラメータを渡さずに動いているのかがさっぱりわからない。
using Microsoft.AspNet.Identity; public class AppUserManager : UserManager<AppUser> { private AppUserManager(IUserStore<AppUser> store) : base(store) { } public static AppUserMananger Create(IdentityFactoryOptions<AppUserMananger> options, IOwinContext context) { return new AppUserMananger(new AppUserStore()); } }
IRole
public class AppRole : IRole<string> { public string Id { get; set; } = Guid.NewGuid().ToString(); public string Name { get; set ; } }
RoleMananager
using Microsoft.AspNet.Identity; public class AppRoleManager : RoleManager<AppRole> { public AppRoleManager(IRoleStore<AppRole, string> store) : base(store) { } }
SignInManager
using Microsoft.AspNet.Identity; using Microsoft.AspNet.Identity.Owin; using Microsoft.Owin; using Microsoft.Owin.Security; public class AppSignInManager : SignInManager<AppUser, string> { private AppSignInManager(UserManager<AppUser, string> userManager, IAuthenticationManager authenticationManager) : base(userManager, authenticationManager) { } public static AppSignInManager Create(IdentityFactoryOptions<AppSignInManager> options, IOwinContext context) { AppUserMananger manager = context.GetUserManager<AppUserMananger>(); return new AppSignInManager(manager, context.Authentication); } }
UserStore
ユーザー情報を扱うためのクラス(CRUD処理)
public class AppUserStore : IUserStore<AppUser>, IUserStore<AppUser,string>, IUserPasswordStore<AppUser,string>, IUserRoleStore<AppUser, string>, IRoleStore<AppRole, string> { // DBの代わりにダミーデータ設定 // ユーザマスタ private static List<AppUser> Users { get; } = new List<AppUser> { new AppUser { Id = "1", UserName = "user1", Password="abc" }, new AppUser { Id = "2", UserName = "user2", Password="def" } }; // ロールマスタ private static List<AppRole> Roles { get; } = new List<AppRole> { new AppRole { Id = "1", Name = "emploryee"}, new AppRole { Id = "999", Name = "admin" } }; // ユーザー・ロールマスタ private static List<Tuple<string, string>> UserRoleMap { get; } = new List<Tuple<string, string>> { Tuple.Create("1", "1"), Tuple.Create("2","999") }; public Task AddToRoleAsync(AppUser user, string roleName) { var role = Roles.FirstOrDefault(x => x.Name == roleName); if (role == null) { throw new InvalidOperationException(); } var userRoleMap = UserRoleMap.FirstOrDefault(x => x.Item1 == user.Id && x.Item2 == role.Id); if (userRoleMap == null) { UserRoleMap.Add(Tuple.Create(user.Id, role.Id)); } return Task.Delay(0); } public Task CreateAsync(AppUser user) { Users.Add(user); return Task.Delay(0); } public Task CreateAsync(AppRole role) { Roles.Add(role); return Task.Delay(0); } public Task DeleteAsync(AppUser user) { Users.Remove(Users.First(x => x.Id == user.Id)); return Task.Delay(0); } public Task DeleteAsync(AppRole role) { Roles.Remove(Roles.First(x => x.Id == role.Id)); return Task.Delay(0); } public void Dispose() { } public Task<AppUser> FindByIdAsync(string userId) { return Task.FromResult(Users.FirstOrDefault(u => u.Id == userId)); } public Task<AppUser> FindByNameAsync(string userName) { return Task.FromResult(Users.FirstOrDefault(u => u.UserName == userName)); } public Task<string> GetPasswordHashAsync(AppUser user) { return Task.FromResult(new PasswordHasher().HashPassword(user.Password)); } public Task<IList<string>> GetRolesAsync(AppUser user) { IList<string> roleNames = UserRoleMap.Where(x => x.Item1 == user.Id) .Select(x => x.Item2) .Select(x => Roles.First(y => y.Id == x)) .Select(x => x.Name) .ToList(); return Task.FromResult(roleNames); } public Task<bool> HasPasswordAsync(AppUser user) { return Task.FromResult(user.Password != null); } public async Task<bool> IsInRoleAsync(AppUser user, string roleName) { var roles = await this.GetRolesAsync(user); return roles.FirstOrDefault(x => x.ToUpper() == roleName.ToUpper()) != null; } public Task RemoveFromRoleAsync(AppUser user, string roleName) { var role = Roles.FirstOrDefault(x => x.Name == roleName); if (role == null) { return Task.FromResult(default(object)); } var userRoleMap = UserRoleMap.FirstOrDefault(x => x.Item1 == user.Id && x.Item2 == role.Id); if (UserRoleMap != null) { UserRoleMap.Remove(userRoleMap); } return Task.Delay(0); } public Task SetPasswordHashAsync(AppUser user, string passwordHash) { user.Password = passwordHash; return Task.Delay(0); } public async Task UpdateAsync(AppUser user) { var target = await this.FindByIdAsync(user.Id); if (target == null) { return; } target.UserName = user.UserName; target.Password = user.Password; return; } public Task UpdateAsync(AppRole role) { var t = Roles.FirstOrDefault(r => r.Id == role.Id); if (t == null) { return Task.FromResult(default(object)); } t.Name = role.Name; return Task.FromResult(default(object)); } Task<AppRole> IRoleStore<AppRole, string>.FindByIdAsync(string roleId) { return Task.FromResult(Roles.FirstOrDefault(u => u.Id == roleId)); } Task<AppRole> IRoleStore<AppRole, string>.FindByNameAsync(string roleName) { return Task.FromResult(Roles.FirstOrDefault(u => u.Name == roleName)); } }
StartUp
ルートのStartUp.csを作成します。
using System; using Microsoft.AspNet.Identity; using Microsoft.AspNet.Identity.Owin; using Microsoft.Owin; using Microsoft.Owin.Security; using Microsoft.Owin.Security.Cookies; using Owin; [assembly: OwinStartup(typeof(MvcWeb2.OwinStartUp))] namespace MvcWeb2 { public class OwinStartUp { public void Configuration(IAppBuilder app) { // 後から「HttpContext.GetOwinContext().Get」で取り出して使える。 // Visual Studioのテンプレートに書いているコメントですが、だそうです。(DBは実装していないので、DbContextは作成していません。 app.CreatePerOwinContext<AppUserMananger>(AppUserMananger.Create); app.CreatePerOwinContext<AppSignInManager>(AppSignInManager.Create); app.CreatePerOwinContext<AppRoleManager>((options, context) => new AppRoleManager(context.Get<AppUserStore>())); app.CreatePerOwinContext<AppSignInManager>((options, context) => new AppSignInManager(context.GetUserManager<AppUserManager>(), context.Authentication)); app.UseCookieAuthentication(new CookieAuthenticationOptions { AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie, LoginPath = new PathString("/Auth/Login") }); } } }
Controller
using Microsoft.AspNet.Identity; using Microsoft.AspNet.Identity.Owin; using System.ComponentModel.DataAnnotations; using System.Threading.Tasks; using System.Web; using System.Web.Mvc; [Authorize] public class AuthController : Controller { private AppSignInManager _appSignInManager; private AppUserManager _appUserManager; public AppSignInManager SignInManager { get { // StartUp.csでCreatePerOwinContext登録したオブジェクトを取り出す。 return _appSignInManager ?? HttpContext.GetOwinContext().Get<AppSignInManager>(); } private set { _appSignInManager = value; } } public AppUserManager UserManager { get { // StartUp.csでCreatePerOwinContext登録したオブジェクトを取り出す。 return _appUserManager ?? HttpContext.GetOwinContext().Get<AppUserManager>(); } private set { _appUserManager = value; } } // GET: Auth/Login [AllowAnonymous] public ActionResult Login(string returnUrl) { ViewBag.ReturnUrl = returnUrl; return View(new LoginViewModel()); } // // POST: /Auth/Login [AllowAnonymous] [HttpPost] public async Task<ActionResult> Login(LoginViewModel model, string returnUrl) { if (!this.ModelState.IsValid) { ViewBag.ReturnUrl = returnUrl; return View(model); } // 認証 (SignInManagerを使用しない場合) //var userManager = new UserManager<AppUser>(new AppUserStore()); //var user = await userManager.FindAsync(model.UserName, model.Password); //if (user == null) //{ // // 認証失敗したらエラーメッセージを設定してログイン画面を表示する // this.ModelState.AddModelError("", "ユーザ名かパスワードが違います"); // ViewBag.ReturnUrl = returnUrl; // return View(model); //} //// クレームベースのIDを作って //var identify = await userManager.CreateIdentityAsync( // user, // DefaultAuthenticationTypes.ApplicationCookie); //// 認証情報を設定 //var authentication = this.HttpContext.GetOwinContext().Authentication; //authentication.SignIn(identify); // SignInManagerを利用する場合 var user = await UserManager.FindAsync(model.UserName, model.Password); if (user == null) { this.ModelState.AddModelError("", "ユーザ名かパスワードが違います"); return View(model); } await SignInManager.SignInAsync(user, false, false); // 元のページへリダイレクト return Redirect(returnUrl); } }
Auth/LoginView
@model MvcWeb2.Controllers.LoginViewModel @{ ViewBag.Title = "Login"; } <h2>Login</h2> @Html.ValidationSummary(true) @* ReturnUrlをパラメータに渡すようにしたフォームを作る *@ @using (Html.BeginForm(new { ReturnUrl = ViewBag.ReturnUrl })) { <div class="form-group"> @Html.LabelFor(m => m.UserName) @Html.TextBoxFor(m => m.UserName) @Html.ValidationMessageFor(m => m.UserName) </div> <div class="form-group"> @Html.LabelFor(m => m.Password) @Html.PasswordFor(m => m.Password) @Html.ValidationMessageFor(m => m.Password) </div> <input type="submit" value="ログイン" class="btn-default" /> }
Auth/LoginViewModel
public class LoginViewModel { [Required(ErrorMessage = "ユーザー名を入れてください")] [Display(Name = "ユーザー名")] public string UserName { get; set; } [Required(ErrorMessage = "パスワードを入れてください")] [Display(Name = "パスワード")] public string Password { get; set; } }
SQL ServerのIdentityカラムの最大値
Identity カラム設定
int型で生成した場合、最大値は「21億(正確には2,147,483,647)」まで採番可能になる。
CREATE TABLE [table1] ( [IDNO] int NOT NULL IDENTITY (1, 1), CONSTRAINT [PK_T_SYSTEM_MON_NEW_HISTORY] PRIMARY KEY CLUSTERED ( [IDNO] ASC ) )
ただし、最大値を超えた場合はエラーとなる。
Identity 最大値を超えた場合
- 型をより大きい型(bigintなど)へ変更する。
- DBCC CHECKIDENTコマンドで番号を初期化する。
-- ID値を0に設定 DBCC CHECKIDENT ('table1', RESEED, 0); -- ID値を100に設定 DBCC CHECKIDENT ('table1', RESEED, 100);
ファイルを分割する。
splitを利用し、大きいファイルを分割する。
split -b 2000m filename.zip filename.zip.
-> 結果 filename.zip.ab, filename.zip.ac, ... 2GB単位で分割される。
分割されたファイルを結合する
cat filename.zip.* > filename.zip
tar圧縮したファイルをそのまま分割する。
tar cvf - *.* | split -b 200m - filename.tar_
-> 結果 filename.tar_ab, filenametar_ac, ... 200MB単位で分割される。
分割りしたファイルを結合と同時に解凍する。
cat filename.tar_* | tar -xvf -
SQL Server LocalDb利用する
LocalDbの作成
Visual Studioから「表示」-「SQL Server オブジェクトエキスプローラー」を表示する。
ローカルDBのデータベースより、新しいデータベースを作成
DB名とファイルの場所を指定して、作成する。
Visual Studioのプロジェクトに追加する。
一番簡単だったのはEntityFrameworkを利用する場合だった。 プロジェクトに新しい項目追加で「ADO.NET Entity Data Model」を追加する。 エータベースからEF Desiginerを選択し、対象のファイルを選択する。
新しいファイルを選択する場合は「新しい接続」より、対象ファイルを選択する。
プロジェクトにモデルデザイナが追加され、「App.config」に「connectionStrings」が追加されている事が確認できる。
<connectionStrings> <add name="App1DBEntities" connectionString="metadata=res://*/Model1.csdl|res://*/Model1.ssdl|res://*/Model1.msl;provider=System.Data.SqlClient;provider connection string="data source=(LocalDB)\MSSQLLocalDB;attachdbfilename=|DataDirectory|App1DB.mdf;integrated security=True;connect timeout=30;MultipleActiveResultSets=True;App=EntityFramework"" providerName="System.Data.EntityClient" /> </connectionStrings>
自動でプロジェクトにmdfファイルがコピーされて入り、filepathがDataDirectoryになってしまう。
※ 特定フォルダーのファイルを参照したい場合は、|DataDirectory|をローカルパスに変更し、プロジェクト内のmdfファイルは削除する。
※ connectionStringsをLocalDBのプロパティの接続文字列を設定しても同じ動作になる。
<connectionStrings> <add name="App1DBEntities" connectionString="(LocalDB)\MSSQLLocalDB;AttachDbFilename=C:\LocalDB\App1DB.mdf;Integrated Security=True;Connect Timeout=30" providerName="System.Data.EntityClient" /> </connectionStrings>
ソース
App1DBEntities db = new App1DBEntities(); foreach (Users item in db.Users) { Console.WriteLine(item.name); }
DBの最新情報更新
DBの最新状態をソースに反映する方法、Entity Data Model画面上で「エータベースからモデルを更新」で最新化できる。