2012年12月19日水曜日

Silverlightがぁぁぁぁぁぁ

Silverlightが終焉するんですかね?

http://www.infoq.com/jp/news/2012/12/silverlight-net-site;jsessionid=E2C9466BE8ADA17A8316DAF4535E4DE6

確かに、便利ではありますが、やはりHTML5がスタンダードだとMSさんも言ってましたし、
今後は、ASP.NET MVCとかに順次移行していくんですかね?

個人的にはASP.NET MVCへの移行は大賛成なんですが、どうなんですかね。

将来的なSilverlightの保守なんかは大変そうだ(´ρ`)

2012年12月11日火曜日

HTTP2.0

ほほぉ~
こんなの出てきましたね。

http://www.infoq.com/jp/news/2012/12/bitz4j-netflix
http://tools.ietf.org/html/draft-ietf-httpbis-http2-00

順調にきまって、より快適なWeb環境を

2012年12月4日火曜日

UbuntuのUnityランチャーへアイコン付きでアプリを登録する

さて、インストールしたわけでもないEclipseのアイコンを普通にUnityに登録しようとすると、
アイコンが無い状態です。

これは自分でインストールしたその他ソフトもそうです。

ってことで、今回は適当に自分インストールしたソフトウェアについて、アイコンをくっつけて
Unityのランチャーに登録してみます。

なお、注意点として、ランチャーへ登録した元ファイルを消すとランチャー側も消えてしまいます。
ですので、*.desktopファイルを作成するときは、デスクトップ以外で作成を行った方が良いです。

手順1

対象となる*.desktopファイルを作成する。
たとえばeclipseであるのであれば、こんな名前です。

eclipse.desktop

とりあえず、適当でも大丈夫です。

手順2

作成したファイルの内容をぺけぺけぺんと記載します。

今回で言えば、eclipseで記載した内容を乗っけておきます。


[Desktop Entry]                                                            
Type=Application
Name=eclipse
GenericName=eclipse client
Icon=/home/sinaku/eclipse/icon.xpm
Exec=/home/sinaku/eclipse/eclipse
Terminal=false

手順3

作成したファイルに実行権限をくっつける。

chmod +x eclipse.desktop

手順4

ランチャーにドラックする

出来上がったものをランチャーにぺけんとのっけるとこんな感じで登録されます。


以上で完了となります。


2012年11月24日土曜日

Ubuntu上のChromeでファイルのダウンロードに失敗

Google Chromeを使い始めてちょっと経ちましたが、不可思議な事が・・・

Eclipseも4.2になったし、新しくいれるかなぁ~っと思って、さらに日本語化をしなきゃなーと思って
何度かダウンロードをしていたのですが、摩訶不思議な事に、ダウンロードしたファイルの解凍ができないんです。

ぉゃ おかしいぞと思って複数回同じファイルをダウンロードしてみたら、Chromeさんがダウンロードするファイルサイズが全部違う・・・

lsでコマンドたたいてダウンロードファイルをサイズ別でソートをすると明らかにおかしなことが起こる・・・

(´-`) ンー 原因はなんだ。

なんかVistaでは昔ダウンロードできなくなる事態があったみたいだけど・・・
そもそもUbuntuだしなOS・・・

誰か助けて下さい(´ρ`)

追記

どうにもサーバが腐ってた・・・
試行回数50回ほどでダウンロードが無事完了・・・これ以上続くなら、本気でマクロかなんか組んで、ダウンロード作業が完了するまでほっとこうかと思ってたが・・・
無事に終わって本当に良かった。

2012年11月22日木曜日

Javaのソース見て汚いいってたら動けば良いとぬかすバカがいたよ

動けば良いというのは、基本的に極論です。
保守などを請け負わないで、作りっぱなしのものでよければそれでもかまわないのかもしれません。
しかし、動けば良いから汚いソースコードでもいいというのは、頭が悪すぎます。

大抵そういう人間は、1秒考えて24時間手を動かす事をする馬鹿が多いです。
普通に考えれば、1時間考えて1時間手を動かすだけで終わる作業を
永遠続けるのです。

結果、時間が無いとか寝言ほざき始めます。

時間が無かったのではなく、時間はあったのにもかかわらず、貴方が無駄に使っただけでしょうというのを何度かいった事がありますが、理解ができない人間が多すぎます。

まっ、あと動けば良いという間抜けな事をいってもいいですが、
毎回思うのが私を巻き込むなと。

動けば良いレベルで作成したんであれば、メンテナンスを考えていないのですから、
メンテナンスを他人にやらせるなと心底思います。

おかげで何度作り直しになった事やら。

とりあえず、毎度毎度思うのが、時間が無いとか寝言ほざく前に、何に自分あ時間を浪費してたのかよく考えてみろってのが1番思いますね。

まっ私今親族が末期癌で入院中で、予期せぬ休みが多々入っているので、
こういった予期せぬ出来事で時間が無いなら、いくらでも協力はしますがね。

その辺の事を考えてほしいものです。


社内での開発環境の仮想化を検討

(´-`) ンー
毎度おなじみで、馬鹿たれどもが、会社のセキュリティうんぬんかんぬんで自分のマシンのセキュリティがどうたらこうたらとぬかし始めたので、仮想環境の検討を始めました。

これは自分自身のマシンを使用しながら、仮想環境内での開発環境構築を行い、
ローカルマシンへのファイルなどのコピーをすべて禁止してしまうという目標です。

そもそも、マシンを別に用意するとか、考え方が頭がおかしいんですよね。
セキュリティ的には、マシンどうこうを含めて、いかに社外に社内データを持ち出せない環境を作るかが問題であって、マシンのセキュリティに重きを置くのがそもそもの間違いなんですよね。

その点をわかってないと、マシンの持ち込みを禁止したから、大丈夫だとぬかして、
USBメモリで持ち出されたデータが何時の間にかなくなって、公開されてる羽目になるので。

さて、そんなこんなで、仮想環境をこうちくするにあたり、1台マシンを購入しました。
これはハイパーバイザ形式での仮想環境の構築を行う為の実験マシンですね。

いくつかの仮想環境を構築する為のソフトには目を付けているのですが、順番に試してみようかと思って、今回マシン購入に踏み切りました。

買ったマシンは下のマシンになります。


意外と安いんです。

メモリさえさしてあげれば、まともに動く仮想環境用のテストマシンとなりそうなので、
買ってみました。
駄目ならダメで、うちの家で仮想環境をこうちくするもよし。
WebサーバとFTPサーバにしてしまうもよしという考えです。

目指す理想の仮想環境は、Web経由でのログインを許して、仮想マシンのビューアは、WindowsであれLinuxであれ同一のビューアが使用できる環境が理想です。

色々試してみたい事もあるので、ちょっと頑張ってみます。

最後に。

マシンの持ち込みを許さないというのに重きを置く間抜けなセキュリティ対策が廃れる事を心の底から望みます。

同時にBYODの利点を最大限に生かしつつ、仮想環境とローカルマシンをうまく組み合わせたセキュリティ対策が行われた開発しやすい環境の構築が今後伸びる事を期待しております。

本買ってきた

C#をメインでやってた私に、誰がとちくるったのか、Javaやれや指令が出ました。
個人的にはJavaは今まで食わず嫌いなところもあったので、んじゃまじめにやってみますかって事で、
本を買ってきました。

以下何の本を買ってきたか。

まずは一冊目。



続いて二冊目。


基本的にVisual Studioで開発してた人間って何で躓くかっていうと
ソフトウェアの使う方で一番躓くと思うんですよね。

ソースはざっと流し読みしても、Javaで書かれている部分って何か特別なものを使ったような
もの以外っていちよう読める事は読めるので。

ただ、どうやって動かすのってので躓くと思う。

ってことで、上の2冊を買ってみました。

続いては、以下の本です。






HTML5とCSS3の本をそろそろ読んでおかなければと思って買った本です。
実際OREILLYさんの本はきっと役に立つだろうと思って買って読んでみようかと。

んで最後に以下の本です。


Gitの本は前々からほしかったのですが、丁度良かったのでついでに購入。
とりあえず読んでみて物足りな変えれば追加購入の予定。

全部読んでみないと何とも言えませんが、とりあえず勤労感謝の日もあるし、ざっくり一通り目を通して、再度3度読みくらいまではしてみたいと考えております。

やっぱ開発者はこの辺の勉強をわすれたらあかんよね。


2012年11月11日日曜日

素数を求める

何やら昔書いたブログの記事にコメントがついていたので、適当にこっちに移行。
 素数を求める簡単なプログラムです。
 たぶん、簡単なプログラミングテストなどに出てくる問題となります。
 んではどうぞ(´ρ`)

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
 
namespace PrimeNumberConsoleApplication
{
    internal class Program
    {
        /// <summary>
        /// 素数求めるプログラム
        /// </summary>
        /// <param name="args"></param>
        private static void Main(string[] args)
        {
            // 2は決め打ち
            Console.WriteLine(@"2");
 
            // 3以上から素数を見ていくけど、偶数は全部2が約数となるので素数対象は奇数のみとなるので2でカウントアップするよ
            for (int i = 3; i <= 1000; i += 2)
            {
                bool hasOuputTarget = true;
 
                // 素数指定で使用する対象の割り切れる数は、対象のiの平方根以下となる。
                // これ以上の割り切れる数となると、平方根以下の約数かける平方根以上の約数の組み合わせしか無い為である。
                // 約数の最小値から検索を初めて、iの平方根までで割り切れない場合は、素数となる
                // 2でカウントアップしてるのは、偶数は見る意味が無い為である。っというかiが奇数のみの場合、偶数でのあまりの確認が必要ない為である。
                for (int j = 3; j <= Math.Sqrt(i); j += 2)
                {
                    if (i % j == 0)
                    {
                        hasOuputTarget = false;
                        break;
                    }
                }
 
                if (hasOuputTarget)
                    Console.WriteLine(i.ToString());
            }
 
            Console.ReadLine();
        }
    }
}

2012年10月31日水曜日

DataGridViewとEntityその2

いくつか間抜けな事をしでかしていたので、ざっくり修正。

属性クラス

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
 
namespace EntitySortSample
{
    /// <summary>
    /// ソート用のEntityに追加するプロパティです。
    /// 単一プロパティによるソートを行った場合、同値だった場合に指定する別プロパティのソートKeyを定義します。
    /// </summary>
    [AttributeUsage(AttributeTargets.Property, AllowMultiple = false)]
    public class SortAttribute : Attribute
    {
        /// <summary>
        /// ソート対象となるプロパティの格納を行っているフィールド
        /// </summary>
        private List<string> _properties;
 
        /// <summary>
        /// ソート対象のプロパティを取得します。
        /// </summary>
        public List<string> Properties { get { return this._properties; } }
 
        /// <summary>
        /// コンストラクタ
        /// </summary>
        /// <param name="properties">比較に仕様する追加プロパティ名</param>
        public SortAttribute(string[] properties)
        {
            this._properties = properties.ToList<string>();
        }
    }
}



ソート方法を実装したIComparer<T>の実装
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Reflection;
using System.Text;
 
namespace EntitySortSample
{
    /// <summary>
    /// IComparer<T>の実装です。
    /// なお、ソート処理対象のプロパティに配列が使用されているような場合は正常に動作しません。
    /// インデクサも同様です。
    /// もっとも、プロパティに配列を使うなという事を一言記載。
    ///
    /// また、プロパティに指定する型は、必ずIComparableの実装が必要となります。
    /// これは、プロパティの値を比較する際に、ジェネリックメソッドにより、ComparableToにて大小比較を行っている為です。
    /// </summary>
    /// <typeparam name="T"></typeparam>
    public class ComparerEx<T> : IComparer<T>
    {
        /// <summary>
        /// ソート対象のプロパティ名
        /// </summary>
        private PropertyDescriptor _propertyDescriptor;
 
        /// <summary>
        /// ソート対象をソートする際のソート方向
        /// </summary>
        private ListSortDirection _listSortDirection;
 
        /// <summary>
        /// コンストラクタ
        /// </summary>
        /// <param name="propertyDescriptor">ソート対象のプロパティ</param>
        /// <param name="listSortDirecton">ソート方向</param>
        public ComparerEx(PropertyDescriptor propertyDescriptor, ListSortDirection listSortDirection)
        {
            this._propertyDescriptor = propertyDescriptor;
            this._listSortDirection = listSortDirection;
        }
 
        /// <summary>
        /// ソート処理で必要な大小比較を行い、処理結果により
        /// マイナス値~プラス値までを戻します。
        /// 完全な同一値の場合は0を返します。
        /// </summary>
        /// <param name="x">比較対象のオブジェクト1です。</param>
        /// <param name="y">比較対象のオブジェクト2です。</param>
        /// <returns>
        /// (昇順ソートの場合。降順は逆になります。)
        /// xがyより小さい場合は、0未満を返します。
        /// xとyが同一の値の場合は0を戻します。
        /// xがyより大きい場合は、0より大きい値を返します。
        /// </returns>
        public int Compare(T x, T y)
        {
            var xPropertyInfo = this.GetPropertyInfo(x, this._propertyDescriptor.Name);
            var yPropertyInfo = this.GetPropertyInfo(y, this._propertyDescriptor.Name);
 
            var xValue = xPropertyInfo.GetValue(x, null);
            var yValue = yPropertyInfo.GetValue(y, null);
 
            var comparableRet = this.Comparable((IComparable)xValue, (IComparable)yValue);
 
            if (comparableRet != 0)
                return comparableRet;
 
            // 同値の場合、PropertyInfoの属性に追加ソート指定項目が存在するかを確認する。
            var xAttributes = xPropertyInfo.GetCustomAttributes(typeof(SortAttribute), false);
            if (xAttributes == null)
                return comparableRet;
 
            // 属性が存在する場合、内部にSortAttributeが定義されているかを確認する。
            foreach (var xAttribute in xAttributes)
            {
                var sortAttribute = xAttribute as SortAttribute;
 
                if (sortAttribute == null)
                    continue;
 
                // SortAttributeの定義が存在する場合は、対象の属性情報に定義されている比較対象の予備プロパティ名を順番に比較していく。
                foreach (var propertyName in sortAttribute.Properties)
                {
                    comparableRet = this.CompareSub(x, y, propertyName);
                    if (comparableRet != 0)
                        return comparableRet;
                }
            }
 
            // ここまで抜けてきた場合は、完全同値の値となる。
            return 0;
        }
 
        /// <summary>
        /// ソート処理で必要な大小比較を行い、処理結果により
        /// マイナス値~プラス値までを戻します。
        /// 完全な同一値の場合は0を返します。
        /// </summary>
        /// <param name="x">比較対象のオブジェクト1です。</param>
        /// <param name="y">比較対象のオブジェクト2です。</param>
        /// <param name="propertyName">比較対象のプロパティです。</param>
        /// <returns>
        /// (昇順ソートの場合。降順は逆になります。)
        /// xがyより小さい場合は、0未満を返します。
        /// xとyが同一の値の場合は0を戻します。
        /// xがyより大きい場合は、0より大きい値を返します。
        /// </returns>
        private int CompareSub(T x, T y, string propertyName)
        {
            var xPropertyInfo = this.GetPropertyInfo(x, propertyName);
            var yPropertyInfo = this.GetPropertyInfo(y, propertyName);
 
            var xValue = xPropertyInfo.GetValue(x, null);
            var yValue = yPropertyInfo.GetValue(y, null);
 
            return this.Comparable((IComparable)xValue, (IComparable)yValue);
        }
 
        /// <summary>
        /// 指定された型に格納されているPropertyInfoの取得を行います。
        /// </summary>
        /// <param name="target">プロパティの情報を取得する対象</param>
        /// <param name="propertyName">取得対象のプロパティ名</param>
        /// <returns></returns>
        private PropertyInfo GetPropertyInfo(T target, string propertyName)
        {
            var propertyInfo = target.GetType().GetProperty(propertyName);
            if (propertyInfo == null)
                throw new ArgumentException(@"指定されてプロパティ名の取得が行えませんでした。");
 
            return propertyInfo;
        }
 
        /// <summary>
        /// 大小比較用のジェネリックメソッドです。
        /// </summary>
        /// <typeparam name="T">比較する型</typeparam>
        /// <param name="x">比較対象の値1</param>
        /// <param name="y">比較対象の値2</param>
        /// <returns>
        /// (昇順ソートの場合。降順は逆になります。)
        /// xがyより小さい場合は、0未満を返します。
        /// xとyが同一の値の場合は0を戻します。
        /// xがyより大きい場合は、0より大きい値を返します。
        /// </returns>
        private int Comparable<T2>(T2 x, T2 y) where T2 : IComparable
        {
            var buf = x.CompareTo(y);
 
            if (this._listSortDirection == ListSortDirection.Ascending)
                return buf;
 
            return buf * -1;
        }
    }
}



最後にBindingListの拡張

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
 
namespace EntitySortSample
{
    /// <summary>
    /// BindingListの拡張クラスです。
    /// </summary>
    /// <typeparam name="T">タイプ</typeparam>
    public class BindingListEx<T> : BindingList<T>
    {
        /// <summary>
        /// ソート項目
        /// </summary>
        private PropertyDescriptor _propertyDescriptor;
 
        /// <summary>
        /// ソート方向(昇順・降順)の保持を行います。
        /// </summary>
        private ListSortDirection _listSortDirection;
 
        /// <summary>
        /// ソート済みかを示す値
        /// </summary>
        private bool _isSortedCore = false;
 
        /// <summary>
        /// ソートのサポートを行う事を宣言
        /// </summary>
        protected override bool SupportsSortingCore
        {
            get
            {
                return true;
            }
        }
 
        /// <summary>
        /// リストのソート順
        /// </summary>
        protected override ListSortDirection SortDirectionCore
        {
            get
            {
                return this._listSortDirection;
            }
        }
 
        /// <summary>
        /// ソート対象
        /// </summary>
        protected override PropertyDescriptor SortPropertyCore
        {
            get
            {
                return this._propertyDescriptor;
            }
        }
 
        /// <summary>
        /// ソート済みかを示す値の取得用
        /// </summary>
        protected override bool IsSortedCore
        {
            get
            {
                return this._isSortedCore;
            }
        }
 
        /// <summary>
        /// コンストラクタ
        /// </summary>
        public BindingListEx()
            : base()
        {
        }
 
        /// <summary>
        /// コンストラクタ
        /// </summary>
        /// <param name="list"></param>
        public BindingListEx(IList<T> list)
            : base(list)
        {
        }
 
        /// <summary>
        /// ソート処理
        /// </summary>
        /// <param name="prop">ソート項目</param>
        /// <param name="direction">ソート方向</param>
        protected override void ApplySortCore(PropertyDescriptor prop, ListSortDirection direction)
        {
            // ソート方向とソートプロパティを格納
            this._propertyDescriptor = prop;
            this._listSortDirection = direction;
 
            // Itemsの存在が無い場合は、処理必要な処理のみ実行して処理を戻します。
            if (base.Items == null || base.Items.Count == 0)
            {
                this._isSortedCore = false;
                base.OnListChanged(new ListChangedEventArgs(ListChangedType.ItemMoved, prop));
 
                return;
            }
 
            // Itemsが存在する場合はComparerExを生成して、比較処理を実行します。
            var items = (List<T>)base.Items;
            var comparerEx = new ComparerEx<T>(this._propertyDescriptor, this._listSortDirection);
            items.Sort(comparerEx);
 
            // ソート処理の終了を設定
            this._isSortedCore = true;
            base.OnListChanged(new ListChangedEventArgs(ListChangedType.ItemMoved, prop));
 
            return;
        }
    }
} 

2012年10月25日木曜日

DataGridViewとEntity

毎度毎度EntityをDataGridにぶち込んだ際に、ソート処理を実装するので、ある程度のサンプルをこちらに記載。

自分用の備忘録で、未テストの適当コードなので注意。

あとでテスト済みをソリューション毎乗っけるかもしれない?

BindingListの拡張

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
 
namespace EntityFrameworkSample
{
    /// <summary>
    /// BindingListの拡張クラスです。
    /// </summary>
    /// <typeparam name="T">タイプ</typeparam>
    public class BindingListEx<T> : BindingList<T>
    {
        /// <summary>
        /// ソート項目
        /// </summary>
        private PropertyDescriptor _propertyDescriptor;
 
        /// <summary>
        /// ソート方向(昇順・降順)の保持を行います。
        /// </summary>
        private ListSortDirection _listSortDirection;
 
        /// <summary>
        /// ソート済みかを示す値
        /// </summary>
        private bool _isSortedCore = false;
 
        /// <summary>
        /// ソートのサポートを行う事を宣言
        /// </summary>
        protected override bool SupportsSortingCore
        {
            get
            {
                return true;
            }
        }
 
        /// <summary>
        /// リストのソート順
        /// </summary>
        protected override ListSortDirection SortDirectionCore
        {
            get
            {
                return this._listSortDirection;
            }
        }
 
        /// <summary>
        /// ソート対象
        /// </summary>
        protected override PropertyDescriptor SortPropertyCore
        {
            get
            {
                return this._propertyDescriptor;
            }
        }
 
        /// <summary>
        /// ソート済みかを示す値の取得用
        /// </summary>
        protected override bool IsSortedCore
        {
            get
            {
                return this._isSortedCore;
            }
        }
 
        /// <summary>
        /// コンストラクタ
        /// </summary>
        public BindingListEx()
            : base()
        {
        }
 
        /// <summary>
        /// コンストラクタ
        /// </summary>
        /// <param name="list"></param>
        public BindingListEx(IList<T> list)
            : base(list)
        {
        }
 
        /// <summary>
        /// ソート処理
        /// </summary>
        /// <param name="prop">ソート項目</param>
        /// <param name="direction">ソート方向</param>
        protected override void ApplySortCore(PropertyDescriptor prop, ListSortDirection direction)
        {
            // ソート方向とソートプロパティを格納
            this._propertyDescriptor = prop;
            this._listSortDirection = direction;
 
            // Itemsの存在が無い場合は、処理必要な処理のみ実行して処理を戻します。
            if (base.Items == null || base.Items.Count == 0)
            {
                this._isSortedCore = false;
                base.OnListChanged(new ListChangedEventArgs(ListChangedType.ItemMoved, prop));
 
                return;
            }
 
            // Itemsが存在する場合はComparerExを生成して、比較処理を実行します。
            var items = (List<T>)base.Items;
            var comparerEx = new ComparerEx<T>(this._propertyDescriptor, this._listSortDirection);
            items.Sort(comparerEx);
 
            // ソート処理の終了を設定
            this._isSortedCore = true;
            base.OnListChanged(new ListChangedEventArgs(ListChangedType.ItemMoved, prop));
 
            return;
        }
    }
}


IComparerの実装

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Reflection;
using System.Text;
 
namespace EntityFrameworkSample
{
    /// <summary>
    /// IComparer<T>の実装です。
    /// なお、ソート処理対象のプロパティに配列が使用されているような場合は正常に動作しません。
    /// インデクサも同様です。
    /// もっとも、プロパティに配列を使うなという事を一言記載。
    ///
    /// また、プロパティに指定する型は、必ずIComparableの実装が必要となります。
    /// これは、プロパティの値を比較する際に、ジェネリックメソッドにより、ComparableToにて大小比較を行っている為です。
    /// </summary>
    /// <typeparam name="T"></typeparam>
    public class ComparerEx<T> : IComparer<T>
    {
        /// <summary>
        /// ソート対象のプロパティ名
        /// </summary>
        private PropertyDescriptor _propertyDescriptor;
 
        /// <summary>
        /// ソート対象をソートする際のソート方向
        /// </summary>
        private ListSortDirection _listSortDirection;
 
        /// <summary>
        /// コンストラクタ
        /// </summary>
        /// <param name="propertyDescriptor">ソート対象のプロパティ</param>
        /// <param name="listSortDirecton">ソート方向</param>
        public ComparerEx(PropertyDescriptor propertyDescriptor, ListSortDirection listSortDirection)
        {
            this._propertyDescriptor = propertyDescriptor;
            this._listSortDirection = listSortDirection;
        }
 
        /// <summary>
        /// ソート処理で必要な大小比較を行い、処理結果により
        /// マイナス値~プラス値までを戻します。
        /// 完全な同一値の場合は0を返します。
        /// </summary>
        /// <param name="x">比較対象のオブジェクト1です。</param>
        /// <param name="y">比較対象のオブジェクト2です。</param>
        /// <returns>
        /// (昇順ソートの場合。降順は逆になります。)
        /// xがyより小さい場合は、0未満を返します。
        /// xとyが同一の値の場合は0を戻します。
        /// xがyより大きい場合は、0より大きい値を返します。
        /// </returns>
        public int Compare(T x, T y)
        {
            var xPropertyInfo = this.GetPropertyInfo(x, this._propertyDescriptor.Name);
            var yPropertyInfo = this.GetPropertyInfo(y, this._propertyDescriptor.Name);
 
            var xValue = xPropertyInfo.GetValue(x, null);
            var yValue = yPropertyInfo.GetValue(y, null);
 
            var comparableRet = this.Comparable((IComparable)xValue, (IComparable)yValue);
 
            if (comparableRet != 0)
                return comparableRet;
 
            // 同値の場合、PropertyInfoの属性に追加ソート指定項目が存在するかを確認する。
            var xAttributes = xPropertyInfo.GetCustomAttributes(typeof(SortAttribute), false);
            if (xAttributes == null)
                return comparableRet;
 
            // 属性が存在する場合、内部にSortAttributeが定義されているかを確認する。
            foreach (var xAttribute in xAttributes)
            {
                var sortAttribute = xAttribute as SortAttribute;
 
                if (sortAttribute == null)
                    continue;
 
                // SortAttributeの定義が存在する場合は、対象の属性情報に定義されている比較対象の予備プロパティ名を順番に比較していく。
                foreach (var propertyName in sortAttribute.Properties)
                {
                    comparableRet = this.CompareSub(x, y, propertyName);
                    if (comparableRet != 0)
                        return comparableRet;
                }
            }
 
            // ここまで抜けてきた場合は、完全同値の値となる。
            return 0;
        }
 
        /// <summary>
        /// ソート処理で必要な大小比較を行い、処理結果により
        /// マイナス値~プラス値までを戻します。
        /// 完全な同一値の場合は0を返します。
        /// </summary>
        /// <param name="x">比較対象のオブジェクト1です。</param>
        /// <param name="y">比較対象のオブジェクト2です。</param>
        /// <param name="propertyName">比較対象のプロパティです。</param>
        /// <returns>
        /// (昇順ソートの場合。降順は逆になります。)
        /// xがyより小さい場合は、0未満を返します。
        /// xとyが同一の値の場合は0を戻します。
        /// xがyより大きい場合は、0より大きい値を返します。
        /// </returns>
        private int CompareSub(T x, T y, string propertyName)
        {
            var xPropertyInfo = this.GetPropertyInfo(x, propertyName);
            var yPropertyInfo = this.GetPropertyInfo(y, propertyName);
 
            var xValue = xPropertyInfo.GetValue(x, null);
            var yValue = yPropertyInfo.GetValue(y, null);
 
            return this.Comparable((IComparable)xValue, (IComparable)yValue);
        }
 
        /// <summary>
        /// 指定された型に格納されているPropertyInfoの取得を行います。
        /// </summary>
        /// <param name="target">プロパティの情報を取得する対象</param>
        /// <param name="propertyName">取得対象のプロパティ名</param>
        /// <returns></returns>
        private PropertyInfo GetPropertyInfo(T target, string propertyName)
        {
            var propertyInfo = target.GetType().GetProperty(propertyName);
            if (propertyInfo == null)
                throw new ArgumentException(@"指定されてプロパティ名の取得が行えませんでした。");
 
            return propertyInfo;
        }
 
        /// <summary>
        /// 大小比較用のジェネリックメソッドです。
        /// </summary>
        /// <typeparam name="T">比較する型</typeparam>
        /// <param name="x">比較対象の値1</param>
        /// <param name="y">比較対象の値2</param>
        /// <returns>
        /// (昇順ソートの場合。降順は逆になります。)
        /// xがyより小さい場合は、0未満を返します。
        /// xとyが同一の値の場合は0を戻します。
        /// xがyより大きい場合は、0より大きい値を返します。
        /// </returns>
        private int Comparable<T>(T x, T y) where T : IComparable
        {
            var buf = x.CompareTo(y);
 
            if (this._listSortDirection == ListSortDirection.Ascending)
                return buf;
 
            return buf * -1;
        }
    }
}


複数プロパティでのソートする際に仕様するカスタム属性の作成

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
 
namespace EntityFrameworkSample
{
    /// <summary>
    /// ソート用のEntityに追加するプロパティです。
    /// 単一プロパティによるソートを行った場合、同値だった場合に指定する別プロパティのソートKeyを定義します。
    /// </summary>
    [AttributeUsage(AttributeTargets.Property, AllowMultiple = false)]
    public class SortAttribute : Attribute
    {
        /// <summary>
        /// ソート対象となるプロパティの格納を行っているフィールド
        /// </summary>
        private List<string> _properties;
 
        /// <summary>
        /// ソート対象のプロパティを取得します。
        /// </summary>
        public List<string> Properties { get { return this._properties; } }
 
        /// <summary>
        /// コンストラクタ
        /// </summary>
        /// <param name="properties">比較に仕様する追加プロパティ名</param>
        public SortAttribute(string[] properties)
        {
            this._properties = properties.ToList<string>();
        }
    }
}

とりあえず、ざっくり記載。
テストした後の修正バージョンを乗っけるかは、要望次第かも?