• 締切済み

C# LINQ 継承クラスに射影充填したい

LINQ for SQLで、DBDataContextにて以下のクラスが自動宣言されています。 public class Job {   public ID { get; set; }   その他大量のフィールドプロパティ(100個くらい) } で、これを継承する以下のクラスがあります。 public class JobE : Job {   いくつかのプロパティ(100個くらい) } LINQ for SQLで、JobEインスタンスに充填したいです。 JobEで追加されたプロパティはすべて初期値でOKです。 using (var context = new DBDataContext()) {   var jobE = context.Jobs     .Where(j => j.xxx == yyy)     .Select(j => new JobE {       現状はここに延々とプロパティを書き連ねています。       (JobE側のプロパティ = Job側のプロパティ)     }); } あまりに馬鹿げていると思います。 もう少し賢い方法はないでしょうか?

みんなの回答

  • shockatz
  • ベストアンサー率80% (153/191)
回答No.2

AutoMapperを使ったらラクかも。 AutoMapper: https://github.com/AutoMapper/AutoMapper ただし、AutoMapperは遅延ローディングには対応していないので、あらかじめメモリ中に実体化してから使うように。 JobEで追加されたプロパティが初期値でいいのなら問題ないかな? Mapper.CreateMap<Job, JobE>(); using (var context = new DBDataContext()) {   var jobE = context.Jobs     .Where(j => j.xxx == yyy)     .ToList()     .Select(j => Mapper.Map<Job, JobE>(j)); }

  • kekyo0
  • ベストアンサー率62% (5/8)
回答No.1

お勧めの方法ではないのですが、Reflectionを使ってコピーする方法があります。 以下の拡張メソッドで、クエリパイプラインをつなげることが出来ます。 // 一応、whereで縛りを入れる public static IEnumerable<T> FakeUpCast<T, U>(this IEnumerable<U> from) where T : U, new() { return new FakeUpCastIterator<T, U>(from); } private sealed class FakeUpCastIterator<T, U> : IEnumerable<T> where T : U, new() { private static readonly object[] emptyIndex_ = new object[0]; private static readonly IEnumerable<PropertyInfo> properties_ = from pi in typeof(U).GetProperties() where pi.CanRead && pi.CanWrite && pi.GetIndexParameter().Length == 0 select pi; private readonly IEnumerable<U> from_; public FakeUpCastIterator(IEnumerable<U> from) { from_ = from; } public IEnumerator<T> GetEnumerator() { foreach (var value in from) { var newValue = new T(); foreach (var pi in properties_) { var pv = pi.GetValue(value, emptyIndex_); pi.SetValue(newValue, pv, emptyIndex_); } yield return newValue; } } IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); } } // 使うとき var jobE = (from job in context.Jobs where job.xxx == yyy select job). FakeUpCast<JobE>();

関連するQ&A