簡體   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