Использование общих типов с Entity Framework и моделями ADO.NET - PullRequest
1 голос
/ 18 августа 2011

Есть ли способ использовать универсальные методы с Entity Frameworks?

Например, у меня есть таблицы: TblPlan и TblTier.Могу ли я передать их в общем методе и найти тип?Каждая таблица имеет немного разные значения, и я хочу сравнить значения по-разному для каждой.Я пытался:

public static Dictionary<T, List<T>> checkDuplicates<T>(T something)
   {
      try
      {
         //TblCommissionPlan plan = (TblCommissionPlan)something;
         //var type = typeof(something);
      }
   }

Это не сработало ... какие-либо идеи?

Ответы [ 2 ]

2 голосов
/ 18 августа 2011

Это не цель универсальных методов.Если вы пишете метод с подписью:

public Dictionary<T, List<T>> CheckDuplicates<T>(T something)

, вы определяете «разделяемую логику».Это означает, что одна и та же логика должна работать для каждого T, переданного методу.Если это не так, вы должны ограничить T, используя какое-то ограничение:

public Dictionary<T, List<T>> CheckDuplicates<T>(T something) where T : ISomeInterface

Теперь вы знаете, что каждый T, переданный методу, должен реализовывать ISomeInterface, и вы можете использовать вВ вашем методе любое свойство или метод, объявленный в этом интерфейсе.

Содержимое метода не должно быть разным для различных типов T, но логика может, потому что вы можете вызывать методы и свойства T s, которые могутимеют различную реализацию.Если этого недостаточно, вы можете передать другой параметр - универсальный делегат или некоторый другой универсальный класс, основанный на T, который добавит вам дополнительную логику.

В вашем сценарии вы хотите сравнивать каждый переданный класс по-разному => сравнение не может быть частью вашего метода, но оно должно быть либо частью ваших сущностей, либо вы должны передать дополнительный класс / метод, который будет выполнять сравнение дляметод.

Для реализации сравнения непосредственно в ваших классах вы можете реализовать интерфейс IComparable<T> и объявить свой метод следующим образом:

public Dictionary<T, List<T>> CheckDuplicates<T>(T something) where T : IComparable<T>

Для реализации сравнения вне ваших классов вы можете просто использовать Func<T, T, int> илиреализация IComparer<T>:

public Dictionary<T, List<T>> CheckDuplicates<T>(T something, IComparer<T> comparer)

В любом случае я не уверен, как это связано с структурой сущностей, поскольку сигнатура вашего метода не имеет ничего общего с EF.

1 голос
/ 18 августа 2011

Вот класс, который я использую для отображения свойств одного объекта, сгенерированного EF.

Вы можете использовать это для сравнения двух различных объектов, это должно быть хорошей отправной точкой.

namespace Solutions.Data.Entities
{
    using System;
    using System.Collections.Concurrent;
    using System.Reflection;
    using System.Text;
    using System.Linq;

    public static class EntityExtensions
    {
        #region Fields

        private static readonly ConcurrentDictionary<string, PropertyInfo[]> PropertyInfoCache = new ConcurrentDictionary<string, PropertyInfo[]>();

        #endregion

        #region Extension Methods

        /// <summary>
        /// This method will find all the Properties of Entity and display them in formatted way.
        /// </summary>
        /// <typeparam name="T">Entity Type</typeparam>
        /// <param name="value">Entity value</param>
        /// <returns>Formatted string of the Entity Properties</returns>
        public static string PropertiesToString<T>(this T value) where T : IObjectWithChangeTracker
        {
            var type = typeof(T).FullName;
            if (String.IsNullOrEmpty(type)) return String.Empty;

            CachePropertyInfo<T>(type);

            StringBuilder stringBuilder = new StringBuilder();

            foreach (var propertyInfo in PropertyInfoCache[type])
            {
                stringBuilder.AppendLine(String.Format("{0} : {1}", propertyInfo.Name, propertyInfo.GetValue(value, null)));
            }

            return stringBuilder.ToString();
        }

        /// <summary>
        /// Use reflection to find all propertied if key is not found in list.
        /// </summary>
        /// <typeparam name="T">Entity Type</typeparam>
        /// <param name="type">property fullname</param>
        private static void CachePropertyInfo<T>(string type)
        {
            if (!PropertyInfoCache.ContainsKey(type))
            {
                // Get all public properties of T type where T inherits interface IObjectWithChangeTracker
                var properties =
                    typeof(T).GetProperties(BindingFlags.Public | BindingFlags.Instance).Where(p => p.Name != "ChangeTracker");
                PropertyInfoCache[type] = properties.ToArray();
            }
        }

        #endregion
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...