假设我有接口IApple
和实现它的类Apple
。另外,我有几个扩展Apple
(SpartanApple
,GreenApple
等的类。)
现在,我有以下函数来处理将apple添加到我的数据库中:
public void CreateApple(IApple apple)
{
...
db.Apples.Add(apple); // This will take an object of type Apple, or ANY of its sub-types
db.SaveChanges();
}
问题是db.Apples.Add(apple);
会产生以下编译时错误
Argument 1: cannot convert from 'IApple' to 'Apple'
因此,在将apple
传递给Add()
之前,我需要将apple
转换为适当的类型。我可以通过使用if语句并根据某些属性将{{1}}转换为适当的类型来实现,但是我不希望每次添加新的子类时都要添加新的大小写
我觉得我在这里错过了一些微不足道的东西。有没有更优雅的方式来做到这一点?任何帮助将不胜感激。
答案 0 :(得分:3)
您可以将其投放到Apple
。 EF会在Add
方法中正确找出实际类型:
db.Apples.Add((Apple)apple);
<强>更新强>
正如@AntP所提到的,您可以通过更改方法签名来接受Apple
而不是IApple
来避免投射:
public void CreateApple(Apple apple)
{
...
db.Apples.Add(apple);
答案 1 :(得分:3)
如果CreateApple
的唯一目的是将其保存到仅接受Apple
的存储库,则只需更改签名:
public void CreateApple(Apple apple)
{
...
db.Apples.Add(apple); // This will take an object of type Apple, or ANY of its sub-types
db.SaveChanges();
}
如果在CreateApple
中使用接口的原因是不依赖于实现,那么如果内部需要对{{1}进行处理,那么该模型就会被破坏}。
另一个选择是创建新 Apple
,只需从Apple
映射:
IApple
这样,你仍然松散耦合,可以使用public void CreateApple(IApple apple)
{
Apple newApple = new Apple()
{
Color = apple.Color,
Variety = apple.Variety,
...
}
db.Apples.Add(newApple);
db.SaveChanges();
}
的不同的实现,而无需更改存储库代码。