4

そこで、EFの使用を開始し、それをORMとして使用するアプリケーションを開発しています。問題は、私がドキュメントを掘り下げる時間があまりなかったということです(私はやがてそうする予定です)そして私はいくつかのことに少し迷っています。たとえば、次の2つのクエリがあります。

public static int GetNextPadlockNumber()
        {
            LockersDBEntities1 entities = new LockersDBEntities1();
            var query = (from p in entities.PadLocks select p.PadlockNumber).DefaultIfEmpty(0).Max();
            return (int)query + 1;
        }

        public static Data.PadLock GetPadLockByNumber(int number)
        {
            Data.LockersDBEntities1 entities = new LockersDBEntities1();
            var query = (from p in entities.PadLocks where p.PadlockNumber == number select p).FirstOrDefault();
            return query;
        }

public static int GetNextLockerNumber()
        {
            LockersDBEntities1 entities = new LockersDBEntities1();
            var query = (from l in entities.Lockers select l.LockerNumber).DefaultIfEmpty(0).Max();
            return (int)query+1;
        }

        public static Data.Locker GetLockerByNumber(int number)
        {
            Data.LockersDBEntities1 entities = new LockersDBEntities1();
            var query = (from l in entities.Lockers where l.LockerNumber == number select l).FirstOrDefault();
            return query;
        }

そして、問題は、それらがまったく同じクエリであるということです。ロッカーや南京錠が欲しいと指定せずにこれを行う方法はありませんか?事前にヒーローに感謝します。

4

2 に答える 2

5

LockerNumberPadlockNumberをIdentityAutoincrementフィールドとして使用することもできます。これは、それを実行しているためです。次に、それらに同じ名前を付けます(たとえば、Id)。

そうすれば、「次のロッカー番号を取得する」必要がなくなります。挿入されたすべての新しいエンティティが次に使用可能な番号を取得し、リポジトリパターンを使用すると、これらのメソッドをBaseRepositoryクラスの一般的なメソッドとして次のようにすることができます。

public IEntity GetEntityById(int number)
{
   return ObjectSet.Single(x => x.Id == number);
}
于 2013-01-24T14:59:05.970 に答える
2

EFの素晴らしい点の1つは、そのようなことができることです。これは簡単なことではなく、試行錯誤が必要ですが、データベースの複雑さの多くを抽象化することができます。

さて、それがであると仮定するLockersDBEntities1DbContext、次のようになります。

public static class LockersDBEntities1Extensions
{
   public static int GetNextNumber<T>(
        this LockersDBEntities1 context, 
        Expression<Func<T, int>> getNumberExpression)
   {
     var query = (from item in context.Set<T> 
                  select getNumberExpression(item))
                 .DefaultIfEmpty(0)
                 .Max();
     return (int)query + 1;
    }
}

次のように使用します。

int nextPadlockNumber = new LockersDBEntities1()
                                    .GetNextNumber<Padlock>(p => p.PadlockNumber)

int nextPadlockNumber = new LockersDBEntities1()
                                    .GetNextNumber<Locker>(l => l.LockerNumber)

すべてのエンティティにまたがる番号にアクセスする一般的な方法がないため、getNumberExpression式が必要です。それは過剰設計かもしれませんが、それが問題である場合、私は次のようなことをします:

//this should be a better name, to reflect the real scenarion
interface ILockNumberProvider 
{
   int Number {get; }
}

Locker、およびPadlockロック番号を提供する必要のある他のクラスにそのインターフェイスを実装します。次に、上記の方法では、式を省略して、次のような一般的な制約を使用できます。

public static class LockersDBEntities1Extensions
{
   public static int GetNextNumber<T>(this LockersDBEntities1 context)
                     where T:ILockNumberProvider 
   {
     var query = (from item in context.Set<T> 
                  select item.Number)
                 .DefaultIfEmpty(0)
                 .Max();
     return (int)query + 1;
    }
}
于 2013-01-24T15:03:56.603 に答える