【发布时间】:2021-02-25 16:06:00
【问题描述】:
我在带有 Sqlite 的 Xamarin Forms 4.8 应用程序中使用 Entity Framework Core 3.1。
对于实体,我有一个小的继承树,并使用一个接口来标记某种类型的实体。结构如下所述。在我的数据访问中,我有一些方法只允许用于实现接口INotificationEntity 的实体。数据访问使用具有Entity 类型约束的泛型,因此我在运行时检查实体是否正在实现INotificationEntity。 Entity 本身从未实现 INotificationEntity。
在我的数据访问中,我使用以下代码,在 Where 和 CountAsync() 语句中将其转换为接口:
public abstract class DataAccess<TTaskData, TEntity> : DataAccessBase,
IDataAccess<TData>
where TData : Data
where TEntity : Entity, new()
...
public async Task<int> CountAsync()
{
...
// usage in CountAsync
return await dbSet.CountAsync(x => ((INotificationEntity)x).NotificationState != NotificationState.Done);
...
}
public async Task<int> GetPendingAsync(int tvdNumber)
{
....
// usage in Where
var result = await dbSet
.AsNoTracking()
.Where(x => ((INotificationEntity)x).NotificationState != NotificationState.Done)
.OrderByDescending(x => x.EventDate)
.ToListAsync()
.ConfigureAwait(false);
...
}
实体的简化结构:
public interface INotificationEntity
{
NotificationState NotificationState { get; set; }
}
public abstract class Entity
{
public int Id { get; set; }
public DateTime EventDate { get; set; }
}
public class NotificationEntity : Entity, INotificationEntity
{
public NotificationState NotificationState { get; set; }
}
代码正在编译和工作。如果有任何不想要的事情发生,我不是 100% 知道的。据我了解文档,如果这会导致客户端评估查询,EF Core 3.1 会抛出异常。但是还有其他可能的陷阱或影响吗?
我为什么要这样做?我只是想避免为数据访问、实体、接口和所有内容创建更大的继承树。
【问题讨论】:
-
在这些方法的约束中添加
INotificationEntity不是更好吗?保存自己的演员表。 -
@insane_developer 泛型声明及其约束在类级别,而不是在方法级别。实现类然后声明它们用来覆盖数据访问基类的实际类。
-
请注意,如果查询完全在服务器上执行,则强制转换可能是无操作的。即,在您的 C# 代码中需要它来编译它,但它可能不会生成任何额外的 SQL 代码。 (分析您的查询以查看它的作用。)
-
您的
DataAccess类允许超过INotificationEntitys,因此转换可能会失败。 -
@GertArnold 我知道这一点,并在此之前检查该类型是否实现了接口。
标签: c# entity-framework-core entity-framework-core-3.1