繁体   English   中英

将通用类型与实体框架和ADO.NET模型一起使用

[英]Using Generic Types with Entity Framework & ADO.NET models

有没有办法在实体框架中使用通用方法?

例如,我有两个表: TblPlanTblTier 我可以通过通用方法传递它们并找到类型吗? 每个表的值略有不同,我想比较每个表的值。 我试过了:

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

这些没有用...有什么想法吗?

那不是通用方法的目的。 如果编写具有签名的方法:

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的方法和属性,这些方法和属性可能具有不同的实现。 如果还不够,您可以传递另一个参数-泛型委托或基于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无关。

这是我用来显示由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
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM