[英]Using Generic Types with Entity Framework & ADO.NET models
有没有办法在实体框架中使用通用方法?
例如,我有两个表: TblPlan
和TblTier
。 我可以通过通用方法传递它们并找到类型吗? 每个表的值略有不同,我想比较每个表的值。 我试过了:
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.