我有以下通用類
public class EFBatchOperation<TContext, T> : IEFBatchOperationBase<TContext, T>, IEFBatchOperationFiltered<TContext, T>
where T : class
where TContext : DbContext{
private ObjectContext context;
private DbContext dbContext;
private IDbSet<T> set;
private Expression<Func<T, bool>> predicate;
public EFBatchOperation(TContext context, IDbSet<T> set)
{
this.dbContext = context;
this.context = (context as IObjectContextAdapter).ObjectContext;
this.set = set;
}
public static IEFBatchOperationBase<TContext, T> For<TContext, T>(TContext context, IDbSet<T> set)
where TContext : DbContext
where T : class
{
return new EFBatchOperation<TContext, T>(context, set);
}
public BatchOperationResult InsertAll<TEntity>(IEnumerable<TEntity> items, DbConnection connection = null, int? batchSize = null) where TEntity : class, T
{
// the problem is here I want to call the current function 'InsertAll' but after changing the type of the function. passing a different type to the function. I tried the following but its not working
var objectContext = ((IObjectContextAdapter)this.dbContext).ObjectContext;
var os = objectContext.CreateObjectSet<TEntity>();
var foreignKeyProperties = os.EntitySet.ElementType.NavigationProperties.Where(x => x.ToEndMember.RelationshipMultiplicity == RelationshipMultiplicity.Many);
Type entityType = typeof(TEntity);
foreach (var foreignKeyProperty in foreignKeyProperties)
{
var childProperty = foreignKeyProperty.ToEndMember.GetEntityType();
foreach (var item in items)
{
var childValue = entityType.GetProperty(foreignKeyProperty.Name).GetValue(item);
Type childValueType = childProperty.GetType();
//MethodInfo method = typeof(EFBatchOperation).GetMethod("InsertAll");
MethodInfo method = typeof(EFBatchOperation<TContext, T>).GetMethod("InsertAll");
var newMethod = method.MakeGenericMethod(new[] { childValueType.DeclaringType });
newMethod.Invoke(this, new object[] { childValue });
// InsertAll<>(childValue, connection, batchSize);
}
}
}
}
我按如下方式呼叫 InsertAll 函式:
BatchOperationResult batchOperationResult = EFBatchOperation.For(context, dbSet).InsertAll(collectionOfEntitiesToInsert);
問題是在這里我想呼叫當前函式“InsertAll”,但是在更改了函式的型別之后。將不同的型別傳遞給函式。
我嘗試使用反射呼叫該函式,但使用以下代碼無法正常作業
MethodInfo method = typeof(EFBatchOperation<TContext, T>).GetMethod("InsertAll");
var newMethod = method.MakeGenericMethod(new[] { childValueType });
newMethod.Invoke(this, new object[] { childValue });
我收到以下錯誤
GenericArguments [0],“EntityFramework.Utilities.BatchOperationResult InsertAll [TEntity] (System.Collections.Generic.IEnumerable
1 [TEntity], System.Data.Common .DbConnection, System.Nullable1 [System.Int32]) 的“ System.Data.Entity.Core.Metadata.Edm.EntityType” “超過” TEntity”型別約束。
更新:
- 這里的想法是插入與子元素相關的屬性,因為原始代碼只是插入了主物體,而不是子元素。
- Also Updated the code with more code to clarify what i am trying to do here
uj5u.com熱心網友回復:
我假設該型別T是所有模型物體都擴展的某個基類?包括這個childValueType?
從錯誤訊息來看,System.Data.Entity.Core.Metadata.Edm.EntityType不符合 上的約束條件TEntity。
EntityType是IEntityType. 雖然你沒有在你的例子中childValueType定義where ,但我相信你已經分配了childValueType = [IEntityType].GetType(), 你想要的地方childValueType = [IEntityType].ClrType。
更新,現在您已經添加了更多代碼。正如我所猜測的那樣;childProperty.GetType();應該是childProperty.ClrType。
uj5u.com熱心網友回復:
謝謝,@JeremyLakeman 指出我完全誤讀了有關int?.
穆罕默德,你的InsertAll方法有where TEntity : class, T限制。即使通過 MakeGenericMethod 通過反射呼叫它,您仍然不能傳遞任何任意型別 - 您必須傳遞滿足該限制的型別。這就是錯誤告訴您的內容:您傳遞了一些不滿足class, 或T限制的型別。
那T是來自于一流的EFBatchOperation,它顯然不符合其他物體型別InsertAll嘗試處理。例如,它以 開頭EFBatchOperation<House>,原始方法呼叫是InsertAll<House>,然后嘗試遞回到InsertAll<Tenant>- 并失敗,因為租戶可能不遵守class,House限制。
InsertAll 和 EFBatchOperation 之間的這種關系真的需要嗎?如果沒有,只需將其洗掉并離開where TEntity: class。如果它必須留在那里進行公共呼叫,那么也許可以嘗試撰寫一個可以處理任何型別并且不需要并在遞回時呼叫它的 InsertAll 的私有版本?
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/356470.html
上一篇:訪問串列時物體框架NullReferenceException
下一篇:檢測嵌套型別的泛型
