【问题标题】:Entity Framework - How to create a base entity without generics实体框架 - 如何创建没有泛型的基础实体
【发布时间】:2014-11-24 02:33:26
【问题描述】:

有没有办法编写一个基本实体,其中主键的类型不使用泛型指定?

例如,到目前为止,我一直在这样做:

public class BaseUniqueEntity<T> where T : IComparable, IComparable<T> {
    [Key]
    public T Key{ get; set; }
}

这在当时很好,但现在给我带来了设计问题。例如,在编写通用存储库时,我必须指定两种类型约束:

public interface IRepository<K, E>
    where K : IComparable, IComparable<K>
    where E : BaseUniqueEntity<K>

我只想指定实体的类型E,但我需要K 类型来指定where E : BaseUniqueEntity&lt;K&gt; 约束。

我无法创建 Key 类型的对象,因为在为我创建表时它会搞砸。

所以我想从BaseUniqueEntity 中删除泛型。有没有办法做到这一点?我没有想法,而且我对 Entity Framework 还是很陌生。

【问题讨论】:

  • 你可以 - 让它成为完全定义的东西:intGuidstring,等等。但是你所有的实体都必须有这样的主键类型。
  • 我真的很希望孩子们可以决定他们的密钥是什么类型

标签: c# .net entity-framework generics


【解决方案1】:

有没有办法编写一个基本实体,其中没有使用泛型指定主键的类型?

为什么一定要写一个基础实体?从表面上看,您所做的只是尝试在每个实体上强制执行一个键,而这甚至可能对类型没有意义(复合键可能更有意义,EF 支持)。无论如何,无论如何,实体都需要 Key 属性,那么具体执行的是什么?

没有规则说一切都必须从基类继承。我的建议:如果您认为调用者总是定义键类型没有意义,那么只需编写定义自己的键的类,并使用对它们有意义的类型。

【讨论】:

  • 但是如果没有抽象类或基类,因此没有基本的Key 属性,我该如何构建通用存储库?如果仅由实现实体知道,我将如何获取实体的密钥?
  • @MatiCicero 反射。像这样的东西应该可以工作: var keyProperty = entity.GetProperties().Where(p => Attribute.IsDefined(p, typeof(KeyAttribute)));
  • @MatiCicero 为什么你需要知道Key 属性来构建一个repo?你见过DbSet.Find 方法吗? IQueryable&lt;T&gt;曝光了吗?这不是继承的情况。它满足 Listkov 吗?
【解决方案2】:

如何保留通用 IRepository 接口并定义另一个接口作为默认键(int、guid 等)的快捷方式 像这样的:

public interface IRepository<K, E>
    where K : IComparable, IComparable<K>
    where E : BaseUniqueEntity<K>
{
}

public interface IRepository<E> : IRepository<int, E>
    where E : BaseUniqueEntity<int>
{
}

定义具体Repository时:

public class UserRepository<User>
{
}

【讨论】:

  • 我也想到了这种方法,但我不喜欢为每种可能的Key 类型创建新的IRepisotry
最近更新 更多