如何找到DbSet.Set<T>()
中最大的Id
?
注意: 不是DbSet<TEntity>
。
在运行时,我不知道类型。
背景: 我有20个表/实体,使用通用方法进行处理。
该过程涉及查找该表/实体的最大Id,并将其与手头的记录进行比较。
如果记录的id
大于数据库中的,则将其插入数据库。
到目前为止,我尝试使用反射:
DbSet<T> table = DbContext.Set<T>();
var lastRecord = table.LastOrDefault(); // throws not supported error
var idProperty = lastRecord.GetType().GetProperties()
.FirstOrDefault(p => p.Name.Equals("Id");
int maxId = (int)idProperty.GetValue(lastRecord);
我也尝试过使用接口转换:
interface ICommonEntity
{ // this interface allows the generic method
string StringId { get;} // to know how to handle entity Id's of
int? IntId { get; } // different types (string vs int).
}
var whatever = table.OrderByDescending(e => (e as ICommonEntity).IntId).FirstOrDefault();
int maxId = (whatever as ICommonEntity).IntId ?? 0;
但是上述代码会产生以下错误:
带有类型 xx 的'TypeAs'表达式不受支持,以及类型 yy 的检查。在LINQ to Entities查询中,只支持实体类型和复杂类型。
附加数据: 我的所有实体都有一个名为Id
的列 / 属性,其类型为int
。
我所做的网络搜索主要指向已知类型的解决方案,例如TEntity
,db.Users.xxx()等。
更新
针对Ian的 答案,我不能直接使用Id
。为什么?
我的一个实体具有名为Id
的字段,但其类型为string
。
class EntityStringId : ICommonEntity
{
public string Id { get; set; }
public string StringId => Id;
public int? IntId => null;
}
class EntityIntId : ICommonEntity
{
public int Id { get; set; }
public string StringId => null;
public int? IntId => Id;
}
如果我尝试使用IntId
进行排序,
private void SomeMethod<T>(string file)
//where T : class // original
//where T : ICommonEntity // cannot. DbContext.Set<T>(); requires class
where T : class, ICommonEntity // throws exception
{
var table_T = DbContext.Set<T>();
var maxId = table_T.Max(e => e.IntId); // throws exception ↓
}
在LINQ to Entities中不支持指定类型成员“IntId”。只支持初始化器、实体成员和实体导航属性。
为了更好地理解,我的方法逻辑:
private void ProcessCsvToDb<T>(
DbSet<T> table,
T csvRecord) where T : class
{
var iRecord = csvRecord as ICommonEntity;
T dbRecord = null;
if (!string.IsNullOrEmpty(iRecord.StringId))
{
dbRecord = table.Find(iRecord.StringId);
}
else if (iRecord.IntId != null)
{
dbRecord = table.Find(iRecord.IntId);
}
}
ICommonEntity
接口了吗?你能否只在方法中使用泛型约束呢? - Ian Mercerwhere T:ICommonEntity
,为什么还需要使用as
进行强制转换呢? - Ian Mercer