質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
Entity Framework

Entity Frameworkは、.NET Framework 3.5より追加されたデータアクセス技術。正式名称は「ADO.NET Entity Framework」です。データベースエンジンに依存しておらず、データプロバイダの変更のみで様々なデータベースに対応できます。

Visual Studio

Microsoft Visual StudioはMicrosoftによる統合開発環境(IDE)です。多種多様なプログラミング言語に対応しています。

ASP.NET

ASP.NETは動的なWebサイトやWebアプリケーション、そしてWebサービスを構築出来るようにする為、Microsoftによって開発されたウェブアプリケーション開発フレームワークです。

Q&A

解決済

2回答

5254閲覧

データベースのテーブルを変更したくない

nori0707

総合スコア11

Entity Framework

Entity Frameworkは、.NET Framework 3.5より追加されたデータアクセス技術。正式名称は「ADO.NET Entity Framework」です。データベースエンジンに依存しておらず、データプロバイダの変更のみで様々なデータベースに対応できます。

Visual Studio

Microsoft Visual StudioはMicrosoftによる統合開発環境(IDE)です。多種多様なプログラミング言語に対応しています。

ASP.NET

ASP.NETは動的なWebサイトやWebアプリケーション、そしてWebサービスを構築出来るようにする為、Microsoftによって開発されたウェブアプリケーション開発フレームワークです。

0グッド

0クリップ

投稿2017/11/04 11:25

編集2017/11/05 13:03

環境:Visual Studio 2017, ASP.NET CORE, .NET CORE, EF CORE2, SQLServer2012

既存システムのデータベースを使って、WEBアプリを作ることになりました。
今回、既存データベースに変更を加えられない状況です。

WEBアプリ用にテーブル間でリレーションをはる必要が出てきました。
この時、モデルでリレーションの書き方はわかったのですが、実行すると
データベースをマイグレーションしないと動かないとエラーになりました。

このような場合は、EntityFrameworkのFromSqlで生のSQLを発行すればいいのでしょうか?
その結果をViewに渡した時は、どのように使うのでしょうか。
この時、モデルは不要ですか?

質問ばかりになってしまってすみませんが、よろしくお願いします。


SurferOnWww様
すみません。具体的にはカレンダーマスタとその日付に紐づく情報を取得したいです。
自己解決しましたので、自己解決欄に記します。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2017/11/05 01:03

何故リレーションを張る必要が出てきたのかあたりから、具体的な例を書いてどういうことがしたいか説明できませんか?
guest

回答2

0

ベストアンサー

2017/11/06 09:34 の私のコメントで「後で案を考えて書いておきます」と書きましたが、それを以下に書いておきます。

Microsoft が提供する Northwind サンプルデータベースから Visual Studio 2015 Community のウィザードを使って EF6 ベースの EDM を作り、 Products と Categories テーブルの CategoryID で内部結合と左外部結合を行うサンプルです。Core ではなく .NET Framework ベースです。

using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Mvc; using AdventureWorksLT; using Mvc5App.Extensions; using System.ComponentModel.DataAnnotations; namespace Mvc5App.Controllers { public class HomeController : Controller { private NORTHWINDEntities db = new NORTHWINDEntities(); // 内部結合 public ActionResult InnerJoin() { var list = from p in db.Products join c in db.Categories on p.CategoryID equals c.CategoryID select new JoinedList { ProductID = p.ProductID, ProductName = p.ProductName, CategoryName = c.CategoryName }; return View(list); } // 左外部結合 public ActionResult LeftOuterJoin() { var list = from p in db.Products join c in db.Categories on p.CategoryID equals c.CategoryID into gj from subcat in gj.DefaultIfEmpty() select new JoinedList { ProductID = p.ProductID, ProductName = p.ProductName, CategoryName = subcat.CategoryName ?? String.Empty }; return View(list); } } // Model // (Controller 内に定義したのは単に分けるのが面倒だったから) public class JoinedList { public int ProductID { set; get; } public string ProductName { get; set; } public string CategoryName { set; get; } } }

LINQ で内部結合、外部結合を行う MSDN ライブラリの説明は以下の記事を見てください。

内部結合の実行
https://docs.microsoft.com/ja-jp/dotnet/csharp/linq/perform-inner-joins

左外部結合の実行
https://docs.microsoft.com/ja-jp/dotnet/csharp/linq/perform-left-outer-joins

投稿2017/11/06 04:40

退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

nori0707

2017/11/07 01:59

SurferOnWww様 回答ありがとうございます。 今回、検索しててもEDMの例ばかりだったので、やはりEF6でそのようにしないといけないんですね。 .NET FrameworkのMVC5はフォルダ構成がどうも好きじゃないので、できたら.NET core のMVCパターンで作成したいと思っています。 が、DBに変更を加えられないんじゃしょうがないです。 具体的な回答例、参考にします。 ありがとうございました。
退会済みユーザー

退会済みユーザー

2017/11/07 06:15

もし、フォルダ構造の好き嫌いの問題だけで Core を選択したのであれば、そこは考え直した方が良い(.NET Framework を選んだほうが良い)かもしれませんね。 上の回答で紹介した記事の EDM は以下の記事の (1) ~ (10) の手順で作ったものを流用しています。 スキャフォールディング機能 http://surferonwww.info/BlogEngine/post/2017/07/23/creating-controller-and-view-in-mvc-using-scaffolding-function.aspx Visual Studio Community 2015 のテンプレートを使用して作った ASP.NET MVC5 プロジェクトに Visual Studio のデザイナを利用して、Northwind データベースから EDM を生成して追加してます。 ASP.NET Core と比べてかなり単純・簡単な作業ではないでしょうか? (自分が知らないだけで、昔より Core も進化して、今は .NET と同様に簡単にできるようになっているのかもしれませんが・・・)
nori0707

2017/11/07 10:54

SurferOnWww様 そうですね。フォルダ構造の好き嫌いで選んではダメですね。(笑) スキャフォールディングについては、提示していただいた記事を拝見しましたが、 Coreの方は、PowerShell(NuGETコンソール)でScaffold-DbContextしたら 簡単にモデルが作成されますので、その後、コントローラー、ビューを新規追加で自動生成ですので EDMが絡まないので簡単な気がします。
guest

0

モデルとデータベースのテーブルは常に一緒じゃないといけないと思っていたのですが、
既存データベースにない複数テーブルの情報を扱いたい場合、どうすればいいか解決しました。

1.コントローラーやビューで扱いたいフィールドをモデルに作成する。
ここでは、Aテーブル(Id, Date)、Bテーブル(Title, Price)が必要とする。

using System; namespace MvcSample.Models { public class CalendarList { public int Id { get; set; } public DateTime Date { get; set; } public string Title { get; set; } public decimal Price { get; set; } } }

2.DbContextを作成する

public class CalendarListContext : DbContext { public CalendarListContext(DbContextOptions<CalendarListContext> options) : base(options) { } public DbSet<CalendarList> CalendarLists { get; set; } }

3.コントローラーを作成する

public class CalendarListsController : Controller { private readonly CalendarListContext _context; public CalendarListsController(CalendarListContext context) { _context = context; } public string Index() { var results = _context.CalendarList .FromSql("SELECT A.Id, A.Date, B.Title, B.Price FROM table1 A LEFT OUTER JOIN table2 B ON A.Date = B.Date") .toList(); if (results == null) { return NotFound(); } return View(results); }

4.ビューを作成する

@model IEnumerable<MvcSample.Models.CalendarList> <table> <tr> <th>Date</th> <th>Title</th> <th>Price</th> </tr> @foreach (var item in Model) { <tr> <td>@item.Date</td> <td>@item.Title</td> <td>@item.Price</td> </tr> } </table>

投稿2017/11/05 13:35

nori0707

総合スコア11

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2017/11/06 00:34

試したわけではないのでハズレだったらすみませんが・・・ > 2.DbContextを作成する それは既存の DB に変更を加えないと(自動 Migration するか DB を直接いじるかはともかくとして)全体が機能しないように思われるのですが、違いますか? たぶん、オリジナルのテーブル A, B の Date には FK が張ってない。張ってあればナビゲーションプロパティが使えるが、張ってないので使えない・・・と言うとことから始まった話ではないかと想像しています。 であれば、もっと簡単に、既存の EDM から LINQ で join した結果を取得できると思います。 すみませんが今ちょっと時間が無いので、後で案を考えて書いておきます。
nori0707

2017/11/07 01:54

SurferOnWww様 試した時はマイグレーションせずに試してエラーにはならなかったのですが、DbContextからDbSetを削除すると、デバッグでエラーになりました。 その後マイグレーションすると、新しく作ったモデルのテーブルが作成されていました。 既存テーブルが無事で、新規テーブルは作成してもいいのならありかなーと思いました。 ただ、マイグレーションした時に、既存テーブルA,Bのモデルは不要かなと思って削除したら 既存DBの該当テーブルA,Bが削除されましたので、既存DBへの変更を加える場合、注意しないと 恐ろしいことになりますね。。
退会済みユーザー

退会済みユーザー

2017/11/07 04:47

ということは解決になってないと思いますが、そうであれば解決マークは外しておいていただければと思います。
nori0707

2017/11/07 10:57

DB構造を変更したくないという事なら、解決には至ってないですね。 解決マークは外しました。 新規テーブル作成はオッケーなら、解決ということで。
退会済みユーザー

退会済みユーザー

2017/11/13 02:58

> 新規テーブル作成はオッケーなら、解決ということで。 新規テーブルに既存のテーブルのデータをコピーする作業が必要だと思いますが? それは質問者さんが書いたコードで自動的に面倒を見てはくれないはず。なので OK にはならないかと・・・ 違っていたら指摘ください。
nori0707

2017/11/13 23:53

SurferOnWww様 新規テーブルに既存テーブルのデータをコピーしなくても、テーブルA,テーブルBからデータを取得してくれました。 なので、この作られた新規テーブルは、アクセスされてる間どうなってるのか?謎なんですが。 変なテーブルが複数出来るのも嫌なんで、やはり.NetFrameworkで作ってます。 .NetCoreでできる方法があれば、引き続きよろしくお願いします。
退会済みユーザー

退会済みユーザー

2017/11/14 04:09

> 新規テーブルに既存テーブルのデータをコピーしなくても、テーブルA,テーブルBからデータを取得してくれました。 そうなんですか、知りませんでした。Entity Framework Core 2.0 は自分の理解のはるか上を行っているということのようです。(1.0 でもそうだったのかもしれませんが) > .NetCoreでできる方法があれば、引き続きよろしくお願いします。 質問者さんの環境は、VS2017 Update 3 (Ver. 15.3) から使えるようになった ASP.NET Core 2.0, .NET Core 2.0, Entity Framework Core 2.0 と理解しています。 残念ながら、現在自分の環境で使えるのは VS2015 Update 3 なので、お役に立てそうもありません。 ASP.NET Core 2.0 としての質問ではなく、Entity Framework Core 2.0 の質問として、EF6 で行ったように、既存の DB から Linq を使って join して IEnumerable<T> 型のオブジェクトを取得する方法というような質問を別に立てた方が良いかもしれません。 ところで、逆に質問して恐縮ですが、「Scaffold-DbContextしたら簡単にモデルが作成」とのことですが(質問者さんのコメントによる)、その際に EF6 と同様に .tt ファイルとそれに従属する .cs ファイルが自動生成されるということはないのでしょうか?
nori0707

2017/11/16 12:43

SurferOnWww様 環境はそれで合ってます。 .ttファイルはフォルダ内を検索してみましたが、ありませんでした。 私はVS2008のWebフォームしか使ったことがないので、あまり理解していません。 間違っているコメントをしているかもしれませんが、ご了承ください。 とりあえず、今回はEF&linkで解決したということで受付を終了しますね。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問