C# 强制转换自引用实体,检测泛型类型
有一次,我得到了所有实体的接口:C# 强制转换自引用实体,检测泛型类型,c#,entity-framework,generics,asp.net-core,entity-framework-core,C#,Entity Framework,Generics,Asp.net Core,Entity Framework Core,有一次,我得到了所有实体的接口: public interface IEntity { int Id { get; set; } } 对于某些实体,将存在一个mutationtable,以记录为哪个实体(CRUD)做了什么 我在一个类上实现了接口IEntity,一些实体将继承该接口 public class Entity : IEntity { public int Id { get; set; } } 实体测试继承自实体(因为它是一个实体),并通过对自身的引用实现模拟 pu
public interface IEntity
{
int Id { get; set; }
}
对于某些实体,将存在一个mutationtable,以记录为哪个实体(CRUD)做了什么
我在一个类上实现了接口IEntity
,一些实体将继承该接口
public class Entity : IEntity
{
public int Id { get; set; }
}
实体测试
继承自实体
(因为它是一个实体),并通过对自身的引用实现模拟
public class Test : Entity, IMutation<Test>
{
public ICollection<Mutation<Test>> Mutations { get; set; } = new List<Mutation<Test>>();
}
现在的问题是,我永远不知道我的类型是什么。我知道它必须来自类型ienty
。
但是当我试图将实体解析为IMutation
时,我得到一个错误,即他不能从IMutation
转换为IMutation
。(但是Test
实现了IEntity
)
试着这样做:
IEnumerable<IMutation<IEntity>> mutationEntries =
entries.Select(s => s.Entity).Where(
w =>
w.GetType()
.GetInterfaces()
.Any(
x =>
x.GetTypeInfo().IsGenericType && x.GetGenericTypeDefinition() == typeof(IMutation<>)))
.Select(s => (IMutation<IEntity>)s);
IEnumerable mutationEntries=
条目。选择(s=>s.Entity)。其中(
w=>
w、 GetType()
.GetInterfaces()
.任何(
x=>
x、 GetTypeInfo().IsGenericType&&x.GetGenericTypeDefinition()==typeof(IMutation)))
。选择(s=>(模拟)s);
但我已经在检查我的实体是否实现了IMutation
。
也许有人有个想法,我如何解决这个问题?很难使用非协变且没有非泛型对应项的泛型接口(如
IEnumerable
->IEnumerable
,IQueryable
->IQueryable
等)
在这种情况下,剩下的唯一选择是反射或动态调度
例如,您可以添加如下方法:
private void ProcessMutationEntity<TEntity>(TEntity entity)
where TEntity : IEntity, IMutation<TEntity>
{
entity.Mutations.Add(new Mutation<TEntity> { EntityId = entity.Id, Entity = entity});
}
请将您的ProcessMutationEntity函数更改为
private void ProcessMutationEntity(TEntity entity),其中TEntity:entity,Immutation{entity.Butations.Add(new Mutation{EntityId=entity.Id,entity=entity});}
-您是个天才,伙计!它终于起作用了。你确实帮我多节省了5个小时。给你:)很高兴你帮了我的忙。干杯
public override int SaveChanges()
{
IEnumerable<EntityEntry> entries = ChangeTracker.Entries(); // gets me all entries that were changed
IEnumerable<IEntity> mutationEntries =
entries.Select(s => s.Entity).Where(
w =>
w.GetType()
.GetInterfaces()
.Any(
x =>
x.GetTypeInfo().IsGenericType && x.GetGenericTypeDefinition() == typeof(IMutation<>)))
.Select(s => (IEntity)s);
// so here now I got the entries that implement IMutation<?> <-- call this now ?-type
// what I'd now want to do is:
foreach(var entry in mutationEntries)
{
IMutation<?> mutationEntry = (IMutation<?>)entry;
mutationEntry.Mutations.Add(new Mutation<?>{ /* later on, add here CRUD, Id, user who changed,... */ });
}
return base.SaveChanges();
}
IEnumerable<IMutation<IEntity>> mutationEntries =
entries.Select(s => s.Entity).Where(
w =>
w.GetType()
.GetInterfaces()
.Any(
x =>
x.GetTypeInfo().IsGenericType && x.GetGenericTypeDefinition() == typeof(IMutation<>)))
.Select(s => (IMutation<IEntity>)s);
private void ProcessMutationEntity<TEntity>(TEntity entity)
where TEntity : IEntity, IMutation<TEntity>
{
entity.Mutations.Add(new Mutation<TEntity> { EntityId = entity.Id, Entity = entity});
}
// ...
foreach (var entry in mutationEntries)
{
ProcessMutationEntity((dynamic)entry);
}
// ...