3

コード内で次のようなことをしたい:

item.Stage = Stage.Values.ONE;

Stage.Values.ONE は、定義済みの Stage を表します。

public class Stage
{
    [Key]
    public virtual int StageId { get; set; }
    public string Name { get; set; }
    public TimeSpan Span { get; set; }
}

私は EF CodeFirst を扱っています...そして、定義する段階がたくさんあります。データをデータベースに格納するか、dbContext に格納するか、または何に格納するかはわかりませんが、最も単純な実装を探しています。

私はこれを試しました:

私は次のことを試しました(2つの定数を定義しています):

public class Stage
{
    [Key]
    public virtual int StageId { get; set; }
    public string Name { get; set; }
    public TimeSpan Span { get; set; }

    public static class Values
    {
        public static readonly Stage ONE = new Stage()
            {
                StageId = 0,
                Name = "ONE",
                Span = new TimeSpan(0, 0, 0)
            };
        public static readonly Stage TWO = new Stage()
        {
            StageId = 1,
            Name = "TWO",
            Span = new TimeSpan(0, 0, 10)
        };
}

しかし、ステージを持つエンティティの新しいインスタンスを作成するたびに、新しいステージがデータベースに追加されます。いくつかの一定の段階が必要です。

ステージの使用:

public class Side
{
    public Side()
    {
        Stage = Stage.Values.ONE;  // Adds new Stage to DB, when it should be a reference to the one I defined above
    }
    public virtual Stage Stage { get; set; }
}
4

2 に答える 2

2

これは列挙型のように見えますが、以前に一種の「拡張列挙型」パターンを使用して、ある程度成功しました。これらの値はコードで参照しているため、それらをデータベースにも保存する意味がない場合がありますが、必要に応じて可能です。

この手法については、http: //lostechies.com/jimmybogard/2008/08/12/enumeration-classes/で詳しく説明しています。

基本的に、列挙型に似た多くのサービスを提供する基本クラスを作成し、それから継承して「列挙型クラス」を作成し、コンストラクターを呼び出す静的インスタンスの束を提供します。 .

リンクの腐敗を避けるために、使用する基本クラスを次に示します (クラス全体をプロジェクトのどこかに置くだけです)。下にスクロールして、独自のコードを探します。

public abstract class Enumeration : IComparable
{
    private readonly int _value;
    private readonly string _displayName;

    protected Enumeration()
    {
    }

    protected Enumeration(int value, string displayName)
    {
        _value = value;
        _displayName = displayName;
    }

    public int Value
    {
        get { return _value; }
    }

    public string DisplayName
    {
        get { return _displayName; }
    }

    public override string ToString()
    {
        return DisplayName;
    }

    public static IEnumerable<T> GetAll<T>() where T : Enumeration, new()
    {
        var type = typeof(T);
        var fields = type.GetFields(BindingFlags.Public | BindingFlags.Static | BindingFlags.DeclaredOnly);

        foreach (var info in fields)
        {
            var instance = new T();
            var locatedValue = info.GetValue(instance) as T;

            if (locatedValue != null)
            {
                yield return locatedValue;
            }
        }
    }

    public override bool Equals(object obj)
    {
        var otherValue = obj as Enumeration;

        if (otherValue == null)
        {
            return false;
        }

        var typeMatches = GetType().Equals(obj.GetType());
        var valueMatches = _value.Equals(otherValue.Value);

        return typeMatches && valueMatches;
    }

    public override int GetHashCode()
    {
        return _value.GetHashCode();
    }

    public static int AbsoluteDifference(Enumeration firstValue, Enumeration secondValue)
    {
        var absoluteDifference = Math.Abs(firstValue.Value - secondValue.Value);
        return absoluteDifference;
    }

    public static T FromValue<T>(int value) where T : Enumeration, new()
    {
        var matchingItem = parse<T, int>(value, "value", item => item.Value == value);
        return matchingItem;
    }

    public static T FromDisplayName<T>(string displayName) where T : Enumeration, new()
    {
        var matchingItem = parse<T, string>(displayName, "display name", item => item.DisplayName == displayName);
        return matchingItem;
    }

    private static T parse<T, K>(K value, string description, Func<T, bool> predicate) where T : Enumeration, new()
    {
        var matchingItem = GetAll<T>().FirstOrDefault(predicate);

        if (matchingItem == null)
        {
            var message = string.Format("'{0}' is not a valid {1} in {2}", value, description, typeof(T));
            throw new ApplicationException(message);
        }

        return matchingItem;
    }

    public int CompareTo(object other)
    {
        return Value.CompareTo(((Enumeration)other).Value);
    }
}

これで、コードは次のようになります。

public class Stage : Enumeration
{
    public TimeSpan TimeSpan { get; private set; }

    public static readonly Stage One
        = new Stage (1, "Stage one", new TimeSpan(5));
    public static readonly Stage Two
        = new Stage (2, "Stage two", new TimeSpan(10));
    public static readonly Stage Three
        = new Stage (3, "Stage three", new TimeSpan(15));

    private EmployeeType() { }
    private EmployeeType(int value, string displayName, TimeSpan span) : base(value, displayName) 
    { 
        TimeSpan = span;
    }
}

セットアップが完了したら、.Value をデータベースに保存するだけです。残念ながら私は EF でそれを行っていませんが、nHibernate では、プロパティの「.Value」を保存するようにプロパティに指示するのはかなり簡単です。それを呼び出す:

Stage.FromValue<Stage>(intValue);
于 2013-06-16T01:40:24.040 に答える