我正在使用Entity Framework 4.1和代码优先方法。
我有以下界面
namespace BackupCore.Contracts
{
public interface IEntity
{
DbSet getDbSet(BackupCoreContainer context);
bool isNew() ;
}
}
namespace BackupCore
{
interface IDao<IEntity>
{
IEntity Save(IEntity ent);
IQueryable<IEntity> GetAll();
bool Delete(IEntity ent, out String errMsg);
void SaveChanges();
}
}
尝试创建这样的抽象EntityDao
时......
using BackupCore.Contracts;
namespace BackupCore
{
public abstract class EntityDao<IEntity> : IDao<IEntity>
{
BackupCoreContainer unique;
protected BackupCoreContainer Context
{
get
{
if (unique == null)
{
unique = new BackupCoreContainer();
}
return unique;
}
}
IEntity IDao<IEntity>.Save(IEntity ent)
{
bool isNew;
bool success;
isNew = ent.isNew();
if (isNew)
{
ent.getDbSet(Context).Add(ent);
}
//Context.Entry(ent).State = (isNew) ? EntityState.Added : EntityState.Modified;
SaveChanges();
return ent;
}
我收到两个错误
'IEntity'不包含'isNew'的定义,并且没有扩展方法'isNew'可以找到接受类型'IEntity'的第一个参数(你是否缺少using指令或汇编引用?)
'IEntity'不包含'getDbSet'的定义,并且没有扩展方法'getDbSet'可以找到接受类型'IEntity'的第一个参数(你是否缺少using指令或汇编引用?)
我相信我遗漏了一些非常基本/明显的东西,但是造成这种情况的原因是什么,我该如何解决呢?
答案 0 :(得分:2)
您的定义public abstract class EntityDao<IEntity> : IDao<IEntity>
定义了一个名为IEntity
的类型参数,隐藏您在其他位置定义的名为IEntity
的接口。
为了避免混淆,John(Saunders,在他现在删除的答案中)正确地建议使用标准命名约定来消除这种名称冲突:使用I
前缀接口名称并使用{类型参数名称{1}}。这给了
T
您会发现这仍然无法编译。请注意该方法的参数不再是public abstract class EntityDao<TEntity> : IDao<TEntity>
{
TEntity IDao<TEntity>.Save(TEntity ent)
{
bool isNew;
bool success;
isNew = ent.isNew();
if (isNew)
{
ent.getDbSet(Context).Add(ent);
}
//Context.Entry(ent).State = (isNew) ? EntityState.Added : EntityState.Modified;
SaveChanges();
return ent;
}
}
而是IEntity
。编译器还没有任何方法知道为TEntity
提供的类型参数将在TEntity
上定义成员。用于通知编译器这一事实的机制称为&#34;泛型类型约束&#34 ;;也就是说,您将type参数约束为IEntity
或实现IEntity
的类型。这为编译器提供了这些成员可用的保证。
要应用约束,只需在类声明中添加IEntity
子句:
where
不一定要对public abstract class EntityDao<TEntity> : IDao<TEntity>
where TEntity : IEntity
{
//...
的定义进行这些更改,但为了避免混淆,最好这样做:
IDao<>
最后,也没有必要将类型约束添加到interface IDao<TEntity>
{
TEntity Save(TEntity ent);
IQueryable<TEntity> GetAll();
bool Delete(TEntity ent, out String errMsg);
void SaveChanges();
}
的类型参数,但它是可能的。我更喜欢只在编译器严格需要的地方添加类型约束,但是很多人宁愿在这里添加约束,因为它使代码的意图更加清晰:
IDao<>