访问instance
的Id
属性?我有以下代码:
public void InsertOrUpdate(Book book)
{
if (book.Id == default(int)) {
我现在想让它通用:
public class TheRepository<T> : IRepository<T> where T : class
{
public void InsertOrUpdate(T instance)
{
if (instance.Id == default(int))//How can I access Id here
{
context.Set<T>().Add(instance);
我搜索了类似的帖子,我想我应该写一些类似instance.GetType().GetProperty("Id").GetValue()
但我不知道具体如何?
你可以做这样的黑客。定义一个接口,其中只有一个类型为 int
的属性称为 Id
:
interface IHaveId
{
public int Id { get; set; }
}
然后声明您的实体实现接口:
public class Book : IHaveId
泛型存储库类中使用的类型应实现此接口的最后状态。
public class TheRepository<T> : IRepository<T> where T : class, IHaveId
{
public void InsertOrUpdate(T instance)
{
if (instance.Id == default(int))
{
context.Set<T>().Add(instance);
}
}
}
这样做可以避免使用反射,这在一般情况下是非常昂贵的。此外,您的代码现在更加清晰。
目前,编译器对T
一无所知,只知道它是一个类。这意味着它永远无法知道它有一个Id
属性,因为没有什么能阻止你创建一个TheRepository<string>
的实例 - 当然,它没有Id
属性。
您在答案中提到的代码片段,使用反射,不是一个好方法。正如我所提到的,如果您创建一个字符串存储库,会发生什么?此代码必然会失败,因为字符串没有 Id 属性。
在这种情况下,您需要做的是确保类Book
以及您需要在存储库中保留的任何其他实体实现包含 ID 的基类:
public abstract class DataObject
{
public int Id {get;set;}
}
public class Book : DataObject
{}
现在,您可以将存储库限制为继承DataObject
的类:
public class TheRepository<T> : IRepository<T> where T : DataObject
现在,编译器可以确信,无论 T 是什么,T 的任何实例始终继承DataObject
,因此具有Id
属性。