[英]How to have a not mapped, common abstract BaseEntity parent for all entity class in EF6 Database-First?
我正在尝试为数据库实体类实现通用逻辑,因此我想为这样的实体引入一个通用的、未映射的抽象基类。
public abstract class BaseEntity {
public int Id { get; set; }
public byte[] RowVersion { get; set; }
}
我不想在数据库中表示这个基类,而只是在实体模型中的逻辑级别。 该项目是数据库优先项目,具有 EDMX 模型。 如果是 Code-First,我可以(我猜)通过使用适当的 EF 注释( Key
等)注释基类属性来轻松实现这一点。
但是在 EDMX 中,我似乎无法选择不是实体本身的自定义基本类型。 当我尝试添加一个新实体时,它抱怨它没有被映射。
我也尝试过使用像IDbEntity
具有上述 2 个属性的接口,但是当我编写如下的通用方法时(只是一个简单的例子),我收到关于接口属性没有被映射的错误。 似乎 EF 无法识别基本上Id
访问对应于底层实体类型。
public static TDbEntity[] GetByIds<TDbEntity>(this IQueryable<TDbEntity> queryable, int[] ids)
where TDbEntity : IDbEntity
{
return queryable.Where(e => ids.Contain(e.Id)).ToArray();
}
使用 Database-First 时,我根本找不到这种基类的可行选项。 任何帮助,将不胜感激。
对于未来的读者,我将发布我当前的解决方案。
根据@IvanStoev 的评论,我使用接口技术唯一需要的是class
通用约束。 因此,我的扩展方法的这个版本在实现IDbEntity
接口的实体查询上运行良好。
public interface IDbEntity {
int Id { get; }
}
...
public static TDbEntity[] GetByIds<TDbEntity>(this IQueryable<TDbEntity> queryable, int[] ids)
where TDbEntity : class, IDbEntity
{
return queryable.Where(e => ids.Contain(e.Id)).ToArray();
}
然后我修改了我的 Edmx 模型 T4 生成器文件以在需要的地方生成接口引用。 我必须以下列方式扩展以下方法。
public string EntityClassOpening(EntityType entity)
{
var baseTypeNames = new List<string>();
baseTypeNames.Add(_typeMapper.GetTypeName(entity.BaseType));
var hasId = entity.Properties.Any(e => e.Name == @"Id" && _typeMapper.UnderlyingClrType(e.TypeUsage.EdmType) == typeof(int));
if (hasId) {
baseTypeNames.Add(@"IDbEntity");
}
return string.Format(
CultureInfo.InvariantCulture,
"{0} {1}partial class {2}{3}",
Accessibility.ForType(entity),
_code.SpaceAfter(_code.AbstractOption(entity)),
_code.Escape(entity),
_code.StringBefore(" : ", string.Join(", ", baseTypeNames.Where(e => !string.IsNullOrEmpty(e)))));
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.