using System; using System.Collections.Generic; namespace WindowsFormsApplication1 { public class RegressionLine { public RegressionLine(Listdata) { this.Data = data; this.CalcSlopeIntercept(); } private List Data { get; set; } public double Slope { get; private set; } public double Intercept { get; private set; } private void CalcSlopeIntercept() { double sumXY = 0; double sumX = 0; double sumY = 0; double sumX2 = 0; for (int i = 0; i < this.Data.Count; i++) { sumXY += Data[i].X * this.Data[i].Y; sumX += Data[i].X; sumY += this.Data[i].Y; sumX2 += Math.Pow(Data[i].X, 2); } this.Slope = (this.Data.Count * sumXY - sumX * sumY) / (this.Data.Count * sumX2 - Math.Pow(sumX, 2)); this.Intercept = (sumX2 * sumY - sumXY * sumX) / (this.Data.Count * sumX2 - Math.Pow(sumX, 2)); } public double GetExpectancyX(double y) { return (y - this.Intercept) / this.Slope; } public double GetExpectancyY(double x) { return this.Slope * x + this.Intercept; } } }
2017年3月13日月曜日
回帰直線のメモ
2017年2月21日火曜日
大文字、小文字を無視してDistinct
小文字でグループ化したデータのうち最初のデータを取り出す
実行すると CSharpが出力される
using System; using System.Collections.Generic; using System.Linq; public class Hello{ public static void Main(){ // Here your code ! Listdata = new List {"CSharp", "CSHARP", "csharp"}; foreach(string d in data.GroupBy(d => d.ToLower()).Select(d => d.First())){ Console.WriteLine(d); } } }
実行すると CSharpが出力される
2017年2月19日日曜日
デフォルトで許可されていないURLの文字
例えば、ブログなんかをイメージしてもらえればよいのだがタグのリンクを以下のようにしたとする
/Blog/Tags/ASP.NET
/Blog/Tags/SQL+Server
.や半角スペースのエンコードした+なんかが含まれているとアクセスするとエラーになる。
■.を許可する。
認識するために/Web.configに、以下を追加する
まずは対象のパスを指定 今回は/Blog/Tags/の次の部分を対象とするので /Blog/Tags/* としてある。
■+を許可する
+を含んだパスにアクセスすると
以下のエラーが出る
以下設定を追加すると許可される
/Blog/Tags/ASP.NET
/Blog/Tags/SQL+Server
.や半角スペースのエンコードした+なんかが含まれているとアクセスするとエラーになる。
■.を許可する。
認識するために/Web.configに、以下を追加する
まずは対象のパスを指定 今回は/Blog/Tags/の次の部分を対象とするので /Blog/Tags/* としてある。
■+を許可する
+を含んだパスにアクセスすると
以下のエラーが出る
要求フィルター モジュールが、ダブル エスケープ シーケンスを含む要求を拒否するように構成されています。 可能性のある原因: 要求にダブル エスケープ シーケンスが含まれていました。要求フィルターはダブル エスケープ シーケンスを拒否するように Web サーバーで構成されています。 対処方法: applicationhost.config または web.confg ファイルにある configuration/system.webServer/security/requestFiltering@allowDoubleEscaping 設定を確認します。
以下設定を追加すると許可される
2017年2月12日日曜日
バインディング
ViewのデータをPostする際に、Nameの名前が所定のルールに従っていれば自動的に
バインドしてくれるので、Controllerの引数から受け取ることができます。
基本は、InputタグのNameに クラス名.プロパティとかけばバインドしてくれます。
あとは、プロパティがリストだという場合は、 クラス名.プロパティ[インデックス]
クラス自体がリストで受け取るのであれば クラス名[インデックス].プロパティ
といった感じでかけば受け取ることができます。
わかりやすくするため、ViewでHTMLをハードコードします。
Models/Sample.cs
IDとNameを持つだけのクラスです。
適当にHomeという名前のControllerを作成して以下のように書きました
Controllers/HomeController.cs
Views/Home/Create.cshtml
@modelにクラスが設定されていれば、Nameのところでクラス名を省略できます。
Views/Home/Create.cshtml
今度は、クラス内にListがある時
Models/Sample.cs
Views/Home/Create.cshtml
リストはプロパティ名に[インデックス]番号つければバインドできます
今度は、Dictionaryをモデルに持っている時です
Models/Sample.cs
Controllers/HomeController.cs
Views/Home/Create.cshtml
KeyValueのうち、Keyは inputのhiddenに、Valueは取得したいinput要素のNameに指定します。
KeyとValueをペアリングするために Nameにプロパティ名[文字列] が一致する者同士を KeyValueのペアとみなします。
<input type = "hidden" name="プロパティ名[文字列].key" value="キー名" />
<input type = "text" name="プロパティ名[文字列].value" value="値" />
[文字列]はループ処理とかを考えると数字が来やすいけども
keyとvalueをペアリングするための識別子なので、任意の文字を指定できます
今度は、Controllerで受け取る引数をリスト(List)にしてみます。
Models/Sample.cs
Controllers/HomeController.cs
Viewes/Home/Create.cshtml
クラス内でListを使い、そのクラスをリストで受けるとなると、今までの方法を組み合わせるだけです
Models/Sample.cs
Controllers/HomeController.cs
Views/Home/Create.cshtml
何が複数なのかを考えればクラスに[数字]をつけるかプロパティに[数字]をつけるか明確ですね
ちなみに、クラスのインスタンスに、一加工してから格納したいので
ひとまずリストで受け取りたいなんて場合、いちいちクラスを作らなくてもバインドしてくれます
Models/Sample.cs
Controllers/HomeController.cs
を用意。
名前をhogeにしたので、Viewにもhogeの名前でnameにつけます。
Views/Home/Create.cshtml
これで、 List list にも List hogeにもバインドされます。
バインドしてくれるので、Controllerの引数から受け取ることができます。
基本は、InputタグのNameに クラス名.プロパティとかけばバインドしてくれます。
あとは、プロパティがリストだという場合は、 クラス名.プロパティ[インデックス]
クラス自体がリストで受け取るのであれば クラス名[インデックス].プロパティ
といった感じでかけば受け取ることができます。
わかりやすくするため、ViewでHTMLをハードコードします。
Models/Sample.cs
using System; using System.Collections.Generic; using System.Linq; using System.Web; namespace SampleCode.Models { public class Sample { public int ID { get; set; } public string Name { get; set; } } }
IDとNameを持つだけのクラスです。
適当にHomeという名前のControllerを作成して以下のように書きました
Controllers/HomeController.cs
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Mvc; namespace SampleCode.Controllers { public class HomeController : Controller { // GET: Home public ActionResult Create() { return View(); } [HttpPost] public ActionResult Create(Models.Sample sample) { return View(); } } }ブレイクポイントを設定して確認します。
Views/Home/Create.cshtml
@{ ViewBag.Title = "Create"; }Create
@using (Html.BeginForm()) { @Html.AntiForgeryToken() }
@modelにクラスが設定されていれば、Nameのところでクラス名を省略できます。
Views/Home/Create.cshtml
@model SampleCode.Models.Sample @{ ViewBag.Title = "Create"; }Create
@using (Html.BeginForm()) { @Html.AntiForgeryToken() }
今度は、クラス内にListがある時
Models/Sample.cs
using System; using System.Collections.Generic; using System.Linq; using System.Web; namespace SampleCode.Models { public class Sample { public int ID { get; set; } public string Name { get; set; } public ListMemo { get; set; } } }
Views/Home/Create.cshtml
@model SampleCode.Models.Sample @{ ViewBag.Title = "Create"; }Create
@using (Html.BeginForm()) { @Html.AntiForgeryToken() }
リストはプロパティ名に[インデックス]番号つければバインドできます
今度は、Dictionaryをモデルに持っている時です
Models/Sample.cs
using System; using System.Collections.Generic; using System.Linq; using System.Web; namespace SampleCode.Models { public class Sample { public int ID { get; set; } public string Name { get; set; } public DictionaryHash { get; set; } } }
Controllers/HomeController.cs
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Mvc; namespace SampleCode.Controllers { public class HomeController : Controller { // GET: Home public ActionResult Create() { return View(); } [HttpPost] public ActionResult Create(Models.Sample sample) { return View(); } } }
Views/Home/Create.cshtml
@model SampleCode.Models.Sample @{ ViewBag.Title = "Create"; }Create
@using (Html.BeginForm()) { @Html.AntiForgeryToken() }
KeyValueのうち、Keyは inputのhiddenに、Valueは取得したいinput要素のNameに指定します。
KeyとValueをペアリングするために Nameにプロパティ名[文字列] が一致する者同士を KeyValueのペアとみなします。
<input type = "hidden" name="プロパティ名[文字列].key" value="キー名" />
<input type = "text" name="プロパティ名[文字列].value" value="値" />
[文字列]はループ処理とかを考えると数字が来やすいけども
keyとvalueをペアリングするための識別子なので、任意の文字を指定できます
今度は、Controllerで受け取る引数をリスト(List
Models/Sample.cs
using System; using System.Collections.Generic; using System.Linq; using System.Web; namespace SampleCode.Models { public class Sample { public int ID { get; set; } public string Name { get; set; } } }
Controllers/HomeController.cs
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Mvc; namespace SampleCode.Controllers { public class HomeController : Controller { // GET: Home public ActionResult Create() { return View(); } [HttpPost] public ActionResult Create(Listlist) { return View(); } } }
Viewes/Home/Create.cshtml
@model SampleCode.Models.Sample @{ ViewBag.Title = "Create"; }基本は、クラス名[数字].プロパティ ですが、modelで明示してあるので省略してあるだけです。Create
@using (Html.BeginForm()) { @Html.AntiForgeryToken() }
クラス内でListを使い、そのクラスをリストで受けるとなると、今までの方法を組み合わせるだけです
Models/Sample.cs
using System; using System.Collections.Generic; using System.Linq; using System.Web; namespace SampleCode.Models { public class Sample { public int ID { get; set; } public string Name { get; set; } public ListMemo { get; set; } } }
Controllers/HomeController.cs
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Mvc; namespace SampleCode.Controllers { public class HomeController : Controller { // GET: Home public ActionResult Create() { return View(); } [HttpPost] public ActionResult Create(Listlist) { return View(); } } }
Views/Home/Create.cshtml
@model SampleCode.Models.Sample @{ ViewBag.Title = "Create"; }Create
@using (Html.BeginForm()) { @Html.AntiForgeryToken() }
何が複数なのかを考えればクラスに[数字]をつけるかプロパティに[数字]をつけるか明確ですね
ちなみに、クラスのインスタンスに、一加工してから格納したいので
ひとまずリストで受け取りたいなんて場合、いちいちクラスを作らなくてもバインドしてくれます
Models/Sample.cs
using System; using System.Collections.Generic; using System.Linq; using System.Web; namespace SampleCode.Models { public class Sample { public int ID { get; set; } public string Name { get; set; } } }
Controllers/HomeController.cs
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Mvc; namespace SampleCode.Controllers { public class HomeController : Controller { // GET: Home public ActionResult Create() { return View(); } [HttpPost] public ActionResult Create(ListModelに定義せずに Listlist, List hoge) { return View(); } } }
名前をhogeにしたので、Viewにもhogeの名前でnameにつけます。
Views/Home/Create.cshtml
@model SampleCode.Models.Sample @{ ViewBag.Title = "Create"; }Create
@using (Html.BeginForm()) { @Html.AntiForgeryToken() }
これで、 List
Entity Framework 1対1
コンソールアプリケーションで試します。
基本的なことはこちら→ConsoleApplicationでCodeFirst
1対1です。
1つのテーブルにまとめようとするとあるレコードはnullが
入る列とデータが入る列があるので分離してnullを排除した結果
1対1のテーブルになったとか、あると思いますが。
今までどおりに作成していくと、どちらのテーブルがどちらを参照するか表現できません。
そこで、Fluentd APIを利用します。
メインのテーブルと、そのIDを参照する参照テーブルで考えてみます。
model/TableMain.cs
model/TableRef.cs
TableMainIdがTableMainテーブルのidを参照する流れです。
ただし、TableMain.csもTableRef.csもともに public virtual クラス名 で記載しているので
どちらがどちらを参照しているのか、この情報だけだと判断がつきません。
ためしに、Add-Migrationを行うと
model/SampleContext.cs(NG)
下記のように怒られます。
Unable to determine the principal end of an association between the types 'CodeFirst.model.TableRef' and 'CodeFirst.model.TableMain'. The principal end of this association must be explicitly configured using either the relationship fluent API or data annotations.
fluent APIで解決する方法
model/SampleContext.cs
HasMany →1:nの関連
HasRequired→1:1の関連
HasOptional→1:0..1の関連
-------------------------------------
data annotaionsで解決する方法
model/TableRef.cs
[Required]を追加すると期待したリレーションが付きます
基本的なことはこちら→ConsoleApplicationでCodeFirst
1対1です。
1つのテーブルにまとめようとするとあるレコードはnullが
入る列とデータが入る列があるので分離してnullを排除した結果
1対1のテーブルになったとか、あると思いますが。
今までどおりに作成していくと、どちらのテーブルがどちらを参照するか表現できません。
そこで、Fluentd APIを利用します。
メインのテーブルと、そのIDを参照する参照テーブルで考えてみます。
model/TableMain.cs
namespace EntityFramework.model { class TableMain { public int Id { get; set; } public string Name { get; set; } public virtual TableRef TableRef { get; set; } } }
model/TableRef.cs
namespace EntityFramework.model { class TableRef { [Key] public int TableMainId { get; set; } public string Memo { get; set; } public virtual TableMain TableMain { get; set; } } }
TableMainIdがTableMainテーブルのidを参照する流れです。
ただし、TableMain.csもTableRef.csもともに public virtual クラス名 で記載しているので
どちらがどちらを参照しているのか、この情報だけだと判断がつきません。
ためしに、Add-Migrationを行うと
model/SampleContext.cs(NG)
using System.Data.Entity; namespace CodeFirst.model { class SampleContext : DbContext { public DbSetTableMain { get; set; } public DbSet TableRef { get; set; } } }
下記のように怒られます。
Unable to determine the principal end of an association between the types 'CodeFirst.model.TableRef' and 'CodeFirst.model.TableMain'. The principal end of this association must be explicitly configured using either the relationship fluent API or data annotations.
fluent APIで解決する方法
model/SampleContext.cs
using System.Data.Entity; namespace CodeFirst.model { class SampleContext : DbContext { public DbSetTableMain { get; set; } public DbSet TableRef { get; set; } protected override void OnModelCreating(DbModelBuilder modelBuilder) { modelBuilder.Entity () .HasRequired(t => t.TableRef) .WithRequiredPrincipal(t => t.TableMain); } } }
HasMany →1:nの関連
HasRequired→1:1の関連
HasOptional→1:0..1の関連
-------------------------------------
data annotaionsで解決する方法
model/TableRef.cs
sing System.ComponentModel.DataAnnotations; namespace CodeFirst.model { class TableRef { [Key] public int TableMainId { get; set; } public string Memo { get; set; } [Required] public virtual TableMain TableMain { get; set; } } }
[Required]を追加すると期待したリレーションが付きます
2017年2月10日金曜日
Entity Framework 多対多
コンソールアプリケーションで試します。
基本的なことはこちら→ConsoleApplicationでCodeFirst
多対多です。
ブログの記事にタグがぶら下がる状態がまさにそれですね。
イメージしやすいのでこれを題材にいろいろ掘り下げてみます。
記事のテーブル。
名前と本文だけのシンプルな構成
model/Article.cs
タグのテーブル
model/Tag.cs
tagはユニークにしたいので Index(IsUnique=true)をつけています。
ユニーク制約をつけるためには、文字数が最大になっていたらつかないので文字数制限をつけます
プレーンなクラスとDBをつなぐクラス
model/BlogContext.cs
Add-Migrationして Update-Databaseしてテーブルを作成します。
※こまかいとこはすっとばします。
多対多なので自動的に中間テーブル(TagArticles)が作られています。
データを格納してみます。
Program.cs
記事Aに C#とSQL Serverを登録しています。
タグはUniqueキー制約をつけているのでこんな登録の仕方したらだめなわけですが
サンプルということもあって、初回登録で空なのでこんな書き方しています。
記事Bを追加します。
今回は、タグがすでにあることを想定して事前に取得して、なければタグのインスタンスを生成するようにしています。
??演算子で nullだったら後ろの処理をするようにしています。
Program.cs
Program.cs
基本的なことはこちら→ConsoleApplicationでCodeFirst
多対多です。
ブログの記事にタグがぶら下がる状態がまさにそれですね。
イメージしやすいのでこれを題材にいろいろ掘り下げてみます。
記事のテーブル。
名前と本文だけのシンプルな構成
model/Article.cs
using System.Collections.Generic; namespace EntityFramework.model { class Article { public int ID { get; set; } public string Title { get; set; } public string Body { get; set; } //リレーション(相手側が多なのでCollection) public virtual ICollectionTag { get; set; } } }
タグのテーブル
model/Tag.cs
using System.Collections.Generic; using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; namespace EntityFramework.model { class Tag { public int ID { get; set; } [Required] [Index(IsUnique=true)] [MaxLength(50)] public string Name { get; set; } //リレーション(相手側が多なのでCollection) public virtual ICollectionArticle { get; set; } } }
tagはユニークにしたいので Index(IsUnique=true)をつけています。
ユニーク制約をつけるためには、文字数が最大になっていたらつかないので文字数制限をつけます
プレーンなクラスとDBをつなぐクラス
model/BlogContext.cs
using System.Data.Entity; namespace EntityFramework.model { class BlogContext : DbContext { public DbSetArticles { get; set; } public DbSet Tags { get; set; } } }
Add-Migrationして Update-Databaseしてテーブルを作成します。
※こまかいとこはすっとばします。
多対多なので自動的に中間テーブル(TagArticles)が作られています。
データを格納してみます。
Program.cs
using EntityFramework.model; using System.Collections.Generic; namespace EntityFramework { class Program { static void Main(string[] args) { BlogContext db = new BlogContext(); // Article側にTagをぶら下げる Article article = new Article { Body = "Body_A", Title = "Title_A" }; Tag tag1 = new Tag { Name = "C#" }; Tag tag2 = new Tag { Name = "SQL Server" }; article.Tag = new List{ tag1, tag2 }; db.Articles.Add(articleA); db.SaveChanges(); // 登録 } } }
記事Aに C#とSQL Serverを登録しています。
タグはUniqueキー制約をつけているのでこんな登録の仕方したらだめなわけですが
サンプルということもあって、初回登録で空なのでこんな書き方しています。
記事Bを追加します。
今回は、タグがすでにあることを想定して事前に取得して、なければタグのインスタンスを生成するようにしています。
??演算子で nullだったら後ろの処理をするようにしています。
Program.cs
using EntityFramework.model; using System.Collections.Generic; using System.Linq; namespace EntityFramework { class Program { static void Main(string[] args) { BlogContext db = new BlogContext(); // Article側にTagをぶら下げる Article article = new Article { Body = "Body_B", Title = "Title_B" }; Tag tag1 = db.Tags.Where(t => t.Name == "C#").FirstOrDefault(); tag1 = tag1 ?? new Tag { Name = "C#" }; Tag tag2 = db.Tags.Where(t => t.Name == "SQL Server").FirstOrDefault(); tag2 = tag2 ?? new Tag { Name = "SQL Server" }; Tag tag3 = db.Tags.Where(t => t.Name == "ASP.NET").FirstOrDefault(); tag3 = tag3 ?? new Tag { Name = "ASP.NET" }; article.Tag = new List{ tag1, tag2, tag3 }; db.Articles.Add(article); db.SaveChanges(); // 登録 } } }
Program.cs
using EntityFramework.model; using System.Collections.Generic; using System.Linq; namespace EntityFramework { class Program { static void Main(string[] args) { BlogContext db = new BlogContext(); // Article側にTagをぶら下げる Article article = new Article { Body = "Body_C", Title = "Title_C" }; Tag tag1 = db.Tags.Where(t => t.Name == "C#").FirstOrDefault(); tag1 = tag1 ?? new Tag { Name = "C#" }; Tag tag2 = db.Tags.Where(t => t.Name == "ASP.NET").FirstOrDefault(); tag2 = tag2 ?? new Tag { Name = "ASP.NET" }; article.Tag = new List{ tag1, tag2 }; db.Articles.Add(article); db.SaveChanges(); // 登録 } } }
2017年2月8日水曜日
Entity Framework 1対多
コンソールアプリケーションで試します。
基本的なことはこちら→ConsoleApplicationでCodeFirst
1対多です。
ブログの記事にコメントが複数ぶら下がる状態がまさにそれですね。
イメージしやすいのでこれを題材にいろいろ掘り下げてみます。
まずは、記事のテーブル。
名前と本文だけのシンプルな構成
model/Article.cs
コメントも同様にシンプルな構成
model/Comment.cs
プレーンなクラスとDBをつなぐクラス
model/BlogContext.cs
Add-Migrationして Update-Databaseしてテーブルを作成します。
※こまかいとこはすっとばします。
blogの記事とコメントの関係を考えると
まずは、記事が単独で入って、そのあとにコメントがつくことになると思います。
まず記事を適当に挿入します。
Program.cs
今度はコメントがついたので、ID1の記事にコメントを追加します。
Program.cs
今回は、ブログを想定しているので、記事が挿入されてからコメントが追加されましたが、一度に挿入する場合を掲載しておきます。
基本的なことはこちら→ConsoleApplicationでCodeFirst
1対多です。
ブログの記事にコメントが複数ぶら下がる状態がまさにそれですね。
イメージしやすいのでこれを題材にいろいろ掘り下げてみます。
まずは、記事のテーブル。
名前と本文だけのシンプルな構成
model/Article.cs
using System.Collections.Generic; namespace EntityFramework.model { class Article { public int ID { get; set; } public string Title { get; set; } public string Body { get; set; } //リレーション(相手側が多なのでCollection) public virtual ICollectionComment { get; set; } } }
コメントも同様にシンプルな構成
model/Comment.cs
namespace EntityFramework.model { class Comment { public int Id { get; set; } public string Name { get; set; } public string Body { get; set; } //リレーション(相手側が1なのでCollectionじゃない) public virtual Article Article { get; set; } } }
プレーンなクラスとDBをつなぐクラス
model/BlogContext.cs
using System.Data.Entity; namespace EntityFramework.model { class BlogContext : DbContext { public DbSetArticles { get; set; } public DbSet Comments { get; set; } } }
Add-Migrationして Update-Databaseしてテーブルを作成します。
※こまかいとこはすっとばします。
blogの記事とコメントの関係を考えると
まずは、記事が単独で入って、そのあとにコメントがつくことになると思います。
まず記事を適当に挿入します。
Program.cs
namespace EntityFramework { class Program { static void Main(string[] args) { Article article = new Article(); article.Body = "Body_A"; article.Title = "Title_A"; BlogContext db = new BlogContext(); db.Articles.Add(article); db.SaveChanges(); } } }
今度はコメントがついたので、ID1の記事にコメントを追加します。
Program.cs
using EntityFramework.model; using System.Collections.Generic; namespace EntityFramework { class Program { static void Main(string[] args) { int articleId = 1; BlogContext db = new BlogContext(); Article article = db.Articles.Find(articleId); // 追加の仕方は2通り // 記事とコメントの関係は1対多なので // 記事につける場合は、コメントは多なのでリストを追加します。 Comment commentA1 = new Comment { Name = "Name_A1", Body = "Body_A1" }; Comment commentA2 = new Comment { Name = "Name_A2", Body = "Body_A2" }; article.Comment = new List{ commentA1, commentA2 }; //↑articleはDBからとったオブジェクト // コメントに記事情報を与える場合は、記事は1なので単独でセットします。 Comment commentA3 = new Comment { Name = "Name_A3", Body = "Body_A3" }; commentA3.Article = article; db.Comments.Add(commentA3); // commentA3は、単なるクラスのインスタンス。 // DBの情報をもったものに登録してあげる必要ある // 複数コメントを追加する時は、一つコメントをインスタンスして db.Comments.Addに一つずつ追加すればよい db.SaveChanges(); } } }
今回は、ブログを想定しているので、記事が挿入されてからコメントが追加されましたが、一度に挿入する場合を掲載しておきます。
using EntityFramework.model; using System.Collections.Generic; namespace EntityFramework { class Program { static void Main(string[] args) { BlogContext db = new BlogContext(); // 1対多で1側に追加して Contextに追加するパターン Article article1 = new Article { Title = "Title_B", Body = "Body_B" }; Comment comment1 = new Comment { Name = "Name_B", Body = "Body_B" }; article1.Comment = new List{ comment1}; db.Articles.Add(article1); Article article2 = new Article { Title = "Title_C", Body = "Body_C" }; Comment comment2 = new Comment { Name = "Name_C1", Body = "Body_C1" }; Comment comment3 = new Comment { Name = "Name_C2", Body = "Body_C2" }; comment2.Article = article2; comment3.Article = article2; db.Comments.Add(comment2); db.Comments.Add(comment3); db.SaveChanges(); } } }
2017年2月7日火曜日
ConsoleApplicationでCodeFirst
VS2015 Communityでメモ
ASP.NET MVC5をいじってCodeFirstがなかなかいい感じなので
ConsoleApplicationで実行するメモ
まずはEntityFrameworkを追加します。
ツール→NuGetパッケージマネージャー→ソリューションのNuGetパッケージの管理
参照にして、EntityFrameworkで検索。
追加するプロジェクトを選択(ここではCodeFirstって名前にしてるのでそれにチェック)
そしてインストール
これで参照にEntityFrameworkが追加される。
まずは1対多のテーブルを作る。
Blogの記事に対し、コメントをつけるデータを格納する部分を作ります。
ひとまずmodelフォルダ作って格納しておきます。
model/Article.cs
model/Comment.cs
今回は、単純にConsoleApplicationで使うのをメモするだけなので、
NotNullとかの細かい部分は飛ばしていきます。
この2クラスは単なるプレーンなクラスなのでこれらとDBとをつなぐためのクラスを作ります。
model/BlogContext.cs
■DBの準備と接続文字列
SQL ServerにDBを作ります。
SampleCodeDBって名前で作りました。
App.configに接続文字列を追加します。
nameには、先ほど作ったBlogContextを記載します。
接続文字は先ほど作ったDBの情報を記載してください。
■マイグレーションを実行する
ツール→NuGetパッケージマネージャー→パッケージマネージャーコンソール を実行。
PM> Enable-Migrations
これでMigrationsフォルダが作られ、Configuration.csファイルが作られます。
Seedメソッドにデータを書けば初期データを挿入することができますが、今回はProgram.csで普通に追加します。
そのまえにMigrationを行ってテーブルを作成します。
マイグレーションでまず覚えておくのはたった2つ。
Add-MigrationとUpdate-Database
まずは、Migrationのファイルを作ります。前回のマイグレーションから今回のマイグレーションまでの差分を作ります。
PM> Add-Migration Init
(Add-Migration Migration名)
問題なければMigrationsフォルダにMigrationファイルがつくられます。
yyyyMMdd********_マイグレーション名.cs で作られます
データベースに反映します。
PM> Update-Database
エラーがなければDBにテーブルが作られます。
リレーションも張られてます。
■データを挿入
ひとまず、何か簡単にデータを入れてみます。
Program.cs
ASP.NET MVC5をいじってCodeFirstがなかなかいい感じなので
ConsoleApplicationで実行するメモ
まずはEntityFrameworkを追加します。
ツール→NuGetパッケージマネージャー→ソリューションのNuGetパッケージの管理
参照にして、EntityFrameworkで検索。
追加するプロジェクトを選択(ここではCodeFirstって名前にしてるのでそれにチェック)
そしてインストール
これで参照にEntityFrameworkが追加される。
まずは1対多のテーブルを作る。
Blogの記事に対し、コメントをつけるデータを格納する部分を作ります。
ひとまずmodelフォルダ作って格納しておきます。
model/Article.cs
namespace CodeFirst.model { class Comment { public int Id { get; set; } public string Name { get; set; } public string Body { get; set; } //リレーション(相手側が1なのでCollectionじゃない) public virtual Article Article { get; set; } } }
model/Comment.cs
namespace CodeFirst.model { class Comment { public int Id { get; set; } public string Name { get; set; } public string Body { get; set; } //リレーション(相手側が1なのでCollectionじゃない) public virtual Article Article { get; set; } } }
今回は、単純にConsoleApplicationで使うのをメモするだけなので、
NotNullとかの細かい部分は飛ばしていきます。
この2クラスは単なるプレーンなクラスなのでこれらとDBとをつなぐためのクラスを作ります。
model/BlogContext.cs
using System.Data.Entity; namespace CodeFirst.model { class BlogContext : DbContext { public DbSetArticles { get; set; } public DbSet Comments { get; set; } } }
■DBの準備と接続文字列
SQL ServerにDBを作ります。
SampleCodeDBって名前で作りました。
App.configに接続文字列を追加します。
nameには、先ほど作ったBlogContextを記載します。
接続文字は先ほど作ったDBの情報を記載してください。
■マイグレーションを実行する
ツール→NuGetパッケージマネージャー→パッケージマネージャーコンソール を実行。
PM> Enable-Migrations
これでMigrationsフォルダが作られ、Configuration.csファイルが作られます。
Seedメソッドにデータを書けば初期データを挿入することができますが、今回はProgram.csで普通に追加します。
そのまえにMigrationを行ってテーブルを作成します。
マイグレーションでまず覚えておくのはたった2つ。
Add-MigrationとUpdate-Database
まずは、Migrationのファイルを作ります。前回のマイグレーションから今回のマイグレーションまでの差分を作ります。
PM> Add-Migration Init
(Add-Migration Migration名)
問題なければMigrationsフォルダにMigrationファイルがつくられます。
yyyyMMdd********_マイグレーション名.cs で作られます
データベースに反映します。
PM> Update-Database
エラーがなければDBにテーブルが作られます。
リレーションも張られてます。
■データを挿入
ひとまず、何か簡単にデータを入れてみます。
Program.cs
using CodeFirst.model; using System.Collections.Generic; namespace CodeFirst { class Program { static void Main(string[] args) { Article article = new Article(); article.Body = "Body_A"; article.Title = "Title_A"; Listcomments = new List () { new Comment {Name = "Name_A1", Body = "Body_A1" }, new Comment {Name = "Name_A2", Body = "Body_A2" } }; article.Comment = comments; BlogContext db = new BlogContext(); db.Articles.Add(article); db.SaveChanges(); } } }
登録:
投稿 (Atom)