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

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

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

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

LINQ to Entities

LINQ to Entitiesは、言語統合クエリであるLINQをEDMに行う機能を指します。C#/VBといった言語に統合されており、Visual StudioのIntelliSense機能を始めとするコーディングの様々なサポートを受けることが可能です。

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

.NET Framework

.NET Framework は、Microsoft Windowsのオペレーティングシステムのために開発されたソフトウェア開発環境/実行環境です。多くのプログラミング言語をサポートしています。

VB.NET

Microsoft Visual Basic .NETのことで、Microsoft Visual Basic(VB6)の後継。 .NET環境向けのプログラムを開発することができます。 現在のVB.NETでは、.NET Frameworkを利用して開発を行うことが可能です。

Q&A

3回答

2169閲覧

LINQ to Entities ゼロパディングしてソートするOrderByの拡張メソッドを作成したい

mikupedia

総合スコア159

Entity Framework

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

LINQ to Entities

LINQ to Entitiesは、言語統合クエリであるLINQをEDMに行う機能を指します。C#/VBといった言語に統合されており、Visual StudioのIntelliSense機能を始めとするコーディングの様々なサポートを受けることが可能です。

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

.NET Framework

.NET Framework は、Microsoft Windowsのオペレーティングシステムのために開発されたソフトウェア開発環境/実行環境です。多くのプログラミング言語をサポートしています。

VB.NET

Microsoft Visual Basic .NETのことで、Microsoft Visual Basic(VB6)の後継。 .NET環境向けのプログラムを開発することができます。 現在のVB.NETでは、.NET Frameworkを利用して開発を行うことが可能です。

0グッド

0クリップ

投稿2019/10/11 10:17

前提・実現したいこと

LINQ to Entitiesの拡張メソッドでOrderByメソッドは既にあると思いますが、
指定された項目を頭ゼロパディングした指定桁数でOrderBy句を生成する拡張メソッドを作成したいです。

該当ソースコードような感じで実装したいのですが
DbFunctions.Rightメソッドの第一引数のstringArgumentを動的に設定する方法がわからず困っております。
式木などを利用すればもしかしたらできるかなと考えたのですが理解しきれず・・・
式木以外でも他の方法や代替案、アドバイスなどあればご教授いただますか?
コードはVBで記述しておりますが、C#でご回答いただいてもOKです。

該当のソースコード

VB

1Public Function OrderBy(Of TSource)(source As IQueryable(Of TSource), keySelector As Linq.Expressions.Expression(Of Func(Of TSource, String)), length As Integer) As IOrderedQueryable(Of TSource) 2 Dim zeroPadString = String.Empty.PadLeft(length, "0"c) 3 Return source.OrderBy(Function(x) DbFunctions.Right(zeroPadString + "ここにkeySelectorで指定された「x.Table.OrderNo」や「x.Table.OrderNo」といったものを挿入したい", length)) 4End Function

補足情報(FW/ツールのバージョンなど)

VisualStudio 2015 Community
ASP.net MVC5
EntityFramework 6.3.0
.Net Framework 4.6.2

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

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

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

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

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

guest

回答3

0

Linq to Entities の Linq 式で Transact-SQL に変換できない C# のメソッドに代えて、Transact-SQL に変換できる SqlFunctions クラスのメソッドを利用できませんか?

SqlFunctions Class
https://docs.microsoft.com/en-us/dotnet/api/system.data.entity.sqlserver.sqlfunctions?view=entity-framework-6.2.0

上記には質問者さんが望む Transact-SQL の RIGHT に対応しているメソッドは見当たりませんが、質問者さんの目的に使えるものがないか探してみてはいかがですか?

例えば、以下の記事の SqlFunctions.Replicate が Transact-SQL の REPLICATE を生成して SQL Server に投げてくれるそうです。

SqlFunctions.Replicate(String, Nullable<Int32>) Method
https://docs.microsoft.com/en-us/dotnet/api/system.data.entity.sqlserver.sqlfunctions.replicate?view=entity-framework-6.2.0

質問者さんのコードで利用できるかは分かりませんが、Microsoft のサンプルデーターベース Northwind の Employees テーブルを使って、SqlFunctions.Replicate で少なくともパディングはできることは確認できました。

Enployees テーブルの内容は以下の画像を見てください。 

イメージ説明

上記から Visual Studio のウィザードを利用して EDM を生成し、SqlFunctions.Replicate メソッドで FirstName に文字 '0' でパディングを入れるコード例を書いておきます。環境は、VS2015, .NET 4.6.1, EF 6.2 です。

using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Data.Entity; using System.Data; using System.Data.SqlClient; namespace ConsoleAppJoinByLinq { class Program { static void Main(string[] args) { NORTHWINDEntities context = new NORTHWINDEntities(); int length = 10; var emp = from e in context.Employees select new { Id = e.EmployeeID, // これは System.NotSupportedException: LINQ to Entities does not recognize ... となる //PFname = System.Data.Objects.SqlClient.SqlFunctions.Replicate("0", length - e.FirstName.Length) + e.FirstName // これは OK PFname = System.Data.Entity.SqlServer.SqlFunctions.Replicate("0", length - e.FirstName.Length) + e.FirstName }; foreach (var e in emp) { Console.WriteLine($"Id: {e.Id}, PFname: {e.PFname}"); } // 結果は: // Id: 1, PFname: 00000Nancy // Id: 2, PFname: 0000Andrew // Id: 3, PFname: 00000Janet // Id: 4, PFname: 00Margaret // Id: 5, PFname: 0000Steven // Id: 6, PFname: 000Michael // Id: 7, PFname: 0000Robert // Id: 8, PFname: 00000Laura // Id: 9, PFname: 000000Anne } } }

コメントにも書きましたが、自分の環境では System.Data.Objects.SqlClient 名前空間の SqlFunctions クラスのメソッドは System.NotSupportedException: LINQ to Entities does not recognize ... となります。質問者さんの環境では分かりませんが注意してください。

投稿2019/10/12 04:32

退会済みユーザー

退会済みユーザー

総合スコア0

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

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

0

SQL Server - System.Data.SqlClient 限定ですが、結果的には同等の並べ替えになるかと

C#

1using(var db = new MyDbContext()) 2{ 3 var q = db.MyItems 4 .OrderBy(i => System.Data.Entity.SqlServer.SqlFunctions.DataLength(i.OrderNo.Replace("0", " ").TrimStart())) 5 .ThenBy(i => i.OrderNo.Replace("0", " ").TrimStart()) 6 .Select(i => new 7 { 8 i.OrderNo, 9 Length = System.Data.Entity.SqlServer.SqlFunctions.DataLength(i.OrderNo.Replace("0", " ").TrimStart()), 10 a = i.OrderNo.Replace("0", " ").TrimStart() 11 }) 12 .ToArray(); 13}

投稿2019/10/12 03:16

hihijiji

総合スコア4150

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

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

0

LINQ to Entities はプロバイダーを通して LINQ を SQL に直します。
プロバイダーを作ってください。

Entity Framework 6 プロバイダー

投稿2019/10/11 10:26

Zuishin

総合スコア28656

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

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

Zuishin

2019/10/11 10:32

拡張メソッドを新規作成するのではなく、ラムダ式で単純に変換することでできそうな気もします。やってみなければわかりませんが。どのデータベースを使っているかによってもかわってくると思います。
mikupedia

2019/10/11 10:50

早速コメントありがとうございます。 プロバイダーを作成するのは敷居が高そうですね・・・ できればDBの種類を意識せずにもう少し上位側でなるべく単純に済ませたいのが本音です。 >ラムダ式で単純に変換することでできそうな気もします。 このレベルで対応できれば一番いいのですが・・・
Zuishin

2019/10/11 10:54

VB.NET 0埋め」で検索すれば 0 パディングの方法はみつかると思いますが、そういうことではないんでしょうか?
mikupedia

2019/10/11 11:11 編集

LINQ to EntitiesのOrderBy句でのゼロパディングですのでDatabase側でゼロパディングされるようにしたいのです。 なので最終的にLinq文が「Order By RIGHT('00000' + fieldName,5) ASC」のようなSQL文に展開されることを期待しています。
Zuishin

2019/10/11 11:16

プロバイダによって文字列の連結が SQL に自動的に変換されることもあります。これはやってみなければわかりません。一度やってみてください。できなければやはりプロバイダを作る必要があるかもしれません。
Zuishin

2019/10/11 12:08

SQL Server Express でやってみましたが、string.Format を使った場合、対応していませんでした。また、ToString("00000") も対応していませんでした。一度文字列に直して足りない分を埋めるのは複文になるのでできませんでした。 SQL Server Express の場合は、プロバイダを作るしかなさそうです。ほかの対応状況も似たようなものだと思います。
Zuishin

2019/10/11 12:25 編集

データベースが変更できる場合は、ストアドプロシージャやビューや計算列などを使ってモデルそのものにデータベース側から 0 埋めしたプロパティを作るという方法もあるかもしれません。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問