开发者

Using Generic Types with Entity Framework & ADO.NET models

开发者 https://www.devze.com 2023-03-29 16:28 出处:网络
Is there a way to use generic methods with Entity Frameworks? For instance, I have the tables: TblPlan and TblTier. Can I pass these in a generic method and find the type? Each table have slightly di

Is there a way to use generic methods with Entity Frameworks?

For instance, I have the tables: TblPlan and TblTier. Can I pass these in a generic method and find the type? Each table have slightly different values and I want to compare the values differently for each. I tried:

public static Dictionary<T, List<T>> checkDuplicates<T>(T something)
   {
      try
开发者_如何转开发      {
         //TblCommissionPlan plan = (TblCommissionPlan)something;
         //var type = typeof(something);
      }
   }

These didn't work...any ideas?


That is not a purpose of generic methods. If you write a method which has signature:

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

you are defining "a shared logic". It means that the same logic must work for every T passed to the method. If it doesn't you must constraint the T by using some kind of constraint:

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

Now you know that every T passed to the method must implement ISomeInterface and you can use in your method any property or method declared on that interface.

Content of the method is not supposed to be different for different type of T but logic can because you can call Ts methods and properties which can have different implementation. If it is not enough you can pass another parameter - generic delegate or some another generic class based on T which will add some additional logic for you.

In you scenario you want to compare each passed class differently => comparison cannot be part of your method but it must either be part of your entities or you must pass additional class / method which will do the comparison for the method.

For implementing comparison directly in your classes you can implement IComparable<T> interface and declare your method as:

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

For implementing comparison outside of your classes you can simply use Func<T, T, int> or implementation of IComparer<T>:

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

In either case I'm not sure how does this relate to entity framework because signature of your method has nothing to do with EF.


Here is a class I use to show Properties of a single Entity that is Generated by EF.

You can build on this to compare two different Entities, it should be a good starting point.

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
    }
}
0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号