听起来你需要解耦你的层;一般来说,传递 EF 对象,更具体地说,将它们从控制器中扔出是一个坏主意,因为您最终可能会暴露客户不感兴趣(或业务)知道的部分数据模型。
纠正这个问题的一种方法如下(注意:这个例子是即时完成的,严格来说不是“最好的”或最解耦的正确方法,但我想让你朝着正确的方向推进)
接口
您需要做的是定义一个接口来描述客户可能希望看到的 MyThing 的重要属性。您将此接口定义放在一个单独的项目中(比如说“MyInterfaces”)并从您的 EF 项目中引用该项目:
public interface IThing
{
int ID{get;set;}
string Data{get;set;}
}
使用数据传输对象
时,在 Interfaces 项目中创建 IThing 的具体实现数据传输对象:
public class MyThingDTO:IThing
{
public int ID{get;set;}
public string Data{get;set;}
}
注意:严格来说,这个模型应该在项目的各个“层”中重新实现,并且接口项目应该只包含接口,但为了简单起见,我在所有层中使用相同的 DTO。
实体
现在您可以在 EF 项目中定义一个实体,如下所示
public class MyThing:IThing
{
[Key]
[Column("MyThing_ID")
public int ID{get;set;}
[Column("MyThing_Data")
public string Data {Get;set;}
}
数据访问层
现在您可以创建引用实体框架和接口项目的数据访问层项目,并创建某种类,其工作是为 IThings 的请求提供服务
public class MyThingDataService
{
public IThing GetByID(int ID)
{
//EF code to query your database goes here, assuming you have a valid DBContext called "ctx". I won't go into how you might create or inject this, etc, as it's a separate topic e.g Dependency Injection.
var thing = ctx.MyThings.FirstOrDefault();
if (thing!=null)
{
return new MyThingDTO{ID=thing.ID, Data=thing.Data};
}
else{//handle the not found case here}
}
}
引用
最后,您从 MVC 项目中引用您的数据访问层和接口项目,您的控制器代码现在看起来像
public MyThing Get(int id)
{
//assuming you have an instance of MyThingDataService here, injected via DI or manually created, etc.
//strictly speaking we should declare our controller return type as IMyThing
//but this means we have to also decorate the DTO class with some attributes for the serialiser
//(KnownType) and I don't want to confuse things, hence the cast.
return dataService.GetByID(id) as MyThing;
}
现在,对 EF 项目的唯一引用是在中央接口项目中。
您的客户端项目只需要引用 Interfaces 项目(实际上您实际上并不需要这样做,因为您的客户端正在通过 HTTP 接收序列化数据,因此可以自由地在 IMyThing 接口上实现它自己的实现,但它很方便重新 -使用它只是为了节省时间)。
包起来
我提到这只是朝着正确的方向迈出的一步——做一个真正的解耦的实现你需要做更多的工作。- 您的数据访问层也应该由接口定义,并且您应该使用某种 DI 容器将其注入 MVC 控制器;- 您的 Interfaces 项目应该只包含接口,并且每一层都应该实现自己的具体类来表示流经它的数据(即它们都应该有自己的 MyThingDTO 实现 IMyThing 的风格) - 当你这样做时,你会看到你有一个很好的解耦系统,因为没有一个层(MVC、数据访问、EF)相互之间有任何引用,只有集中式接口项目。- 可能比我聪明的人会发现你需要做的其他事情,因为我可能忘记了一些事情 - 现在很早(晚了?)。
反正。希望这可以帮助。