2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

プロパティとしてのクラス(Table Per Type編) 1

2
Last updated at Posted at 2022-03-13

前回までのおさらいと改良

前回では静的メソッドとしての”プロパティとしてのクラス”のgetterとsetterを定義した。
これを汎化拡張メソッドとして書き直した。

ClassAsProperty.cs
namespace ClassAsProperty
{
    public static class ClassAsPropertyMethodBase
    {

        public static T? GetmethodT<T, T2>(this T2 TargetPoperty) where T : struct where T2 : ICompornentClass<T>
        {
            return TargetPoperty?.Value;
        }

        public static void SetmethodT<T, T2>(this T2 TargetProperty, T value) where T : struct where T2 : ICompornentClass<T>, new()
        {
            if (TargetProperty is null)
            { TargetProperty = new T2(); }
            TargetProperty.Value = value;
        }
    }
}

ICompornentClass<T>の中身はこちら

ICompornentClass.cs

    public interface ICompornentClass<T> where T : struct
    {
        public int ID { get; set; }
        public T Value { get; set; }

    }

まず準備はここまで、何をしたかというとICompornetClassを継承したクラスは
GetMethodTとSetMethodTをジェネリックメソッドとして呼び出せるように定義しました。

応用:期限切れ管理クラス

まずはOne to Oneの関係性を念頭に置いた応用として期限日の定義を行います。
Compornentクラスのインターフェイス、Compositeクラスのインターフェイスと実装を以下に示します。

Inpriment of Compornent
    public class ExpireDayCompornent<T>: ICompornentClass<DateTime> where T : AbstractExpiredayBaseClass<T>
    {
        public ExpireDayCompornent() { Value = System.DateTime.Now; }
        public ExpireDayCompornent(DateTime value) { Value = value; }
        public int ID { get; set; }
        public DateTime Value { get; set; }
        public T ExpiredComposteNavigation { get; set; }
    }

上記のジェネリックインターフェイスを用いてCompornentクラスを実装する。

Interface of Composite
    public interface IExpireDayConpositeClass
    {
        public int ID { get; set; }
        public DateTime CreatedDateTime { get; set; }
        public DateTime? ExpiredDateTime();
        public void ExpiredDateTime(DateTime value);
    }

Compositeクラスのインターフェイスを実装しておく。
単に自動実装実装プロパティにしたかったがnullableが問題になったのでオーバーロードで対応した。
これは後でFluent APIでの実装でかかわってくる。

ABC of Composite
    public abstract class AbstractExpiredayBaseClass<T>: IExpireDayConpositeClass where T : AbstractExpiredayBaseClass<T>
    {
        public int ID {get; set;}
        public DateTime CreatedDateTime { get; set; }
        private ExpireDayCompornent<AbstractExpiredayBaseClass<T>> ExpireDayCompornent { get; set; }
        public DateTime? ExpiredDateTime() => ExpireDayCompornent.GetmethodT<DateTime, ExpireDayCompornent<AbstractExpiredayBaseClass<T>>>();
        public void ExpiredDateTime(DateTime value) => ExpireDayCompornent.SetmethodT<DateTime, ExpireDayCompornent<AbstractExpiredayBaseClass<T>>>(value);
    }

これがその実装である。このアブストラクトクラスが継承され実装された後に
自己参照ジェネリックで定義可能である。

独自のFluent API実装に向けて

ところで、このクラスのモデルビルダーを実装すればうまく行くけど
何を返せばいいのか迷うと思うが多分これだ
https://docs.microsoft.com/en-us/dotnet/api/system.data.entity.infrastructure.dbentityentry-1?view=entity-framework-6.2.0

Entity
 public System.Data.Entity.Infrastructure.DbEntityEntry<TEntity> Entry<TEntity> (TEntity entity) where TEntity : class;

このDbEntityEntryを返すジェネリック拡張メソッドにしておけば一発でコンテキスト定義可能なはず。

2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?