C# 具有实体框架的N层应用程序

C# 具有实体框架的N层应用程序,c#,asp.net,asp.net-mvc,entity-framework,n-tier-architecture,C#,Asp.net,Asp.net Mvc,Entity Framework,N Tier Architecture,我用ASP.NET MVC开发了一个n层应用程序。我可以用另一种技术来切换我的DAL。(ADO.NET、Oracle、MySQL等)但首先我使用ADO实体框架。但我应该如何在实体中对关系进行编码?例如,我有一个Product类,它的关系是Category类。(或者我只在我的产品实体中保存CategoryId???)如果我使用EF,我在视图中使用Product.Category.CategoryName(),但我认为这对于n层体系结构是错误的方法。你对这个题目有什么建议 //Entities pu

我用ASP.NET MVC开发了一个n层应用程序。我可以用另一种技术来切换我的DAL。(ADO.NET、Oracle、MySQL等)但首先我使用ADO实体框架。但我应该如何在实体中对关系进行编码?例如,我有一个Product类,它的关系是Category类。(或者我只在我的产品实体中保存CategoryId???)如果我使用EF,我在视图中使用Product.Category.CategoryName(),但我认为这对于n层体系结构是错误的方法。你对这个题目有什么建议

//Entities
public class Product(){
    public int ProductId{get;set;}
    public string ProductName{get;set;}

    //id or class relation? which one???
    public int CategoryId{get;set;}
    public Category Category{get;set;} //This works just Entity Framework of course
}

public Category(){
    public int CategoryId{get;set;}
    public string CategoryName{get;set;}
}


//in my view 
<p>
@Product.Category.CategoryName //I think it's not right approach for n-tier application? Pls suggest.
</p>
//实体
公共类产品(){
public int ProductId{get;set;}
公共字符串ProductName{get;set;}
//身份证还是阶级关系?哪一个???
public int CategoryId{get;set;}
公共类别Category{get;set;}//这当然只适用于实体框架
}
公共类别(){
public int CategoryId{get;set;}
公共字符串CategoryName{get;set;}
}
//在我看来

@Product.Category.CategoryName//我认为这不是n层应用程序的正确方法?请建议。


我通常在实体中包含外键。您还可以将相关的
类别
实体作为属性包含在您的
产品
类中,以用于上述在视图中显示等场景

处理相关实体的一种常见方法是对它们应用
virtual
关键字,允许延迟或快速加载相关实体。通过这种方式,您可以对
产品
类执行CRUD操作,并且可以分配
类别
(通过CategoryId),而不需要类别属性的整个
类别
实体。然后,您可以选择在可能需要关系的查询中包含关系

public class Product
{
    public int ProductId {get;set;}
    public string ProductName {get;set;}

    //id or class relation? both!
    public int CategoryId {get;set;}

    public virtual Category Category {get;set;}
}
快速加载示例:

db.Products.Include(p => p.Category).ToArray();

<p>
@Product.Category.CategoryName 
</p>
db.Products.Include(p=>p.Category.ToArray();

@Product.Category.CategoryName


如果您的
表示层
通过
web服务与
中间层
交互,则您的方法不适用,例如使用EF延迟加载。您可以将包含所有所需属性的平面模型传递给客户端。若您直接引用了表示层中的中间层,而并没有使用web服务,那个么您的方法工作得很好

您应该将数据库逻辑与前端内容分开。查看使用
UnitOfWork
Repository
模式的好例子


在发送对象之前,使用DTO、视图或其他方式展平对象,或者至少不要延迟加载它们。对于帮助创建DTO/非db对象非常有用。

Virtual还允许更改跟踪,对吗?它之所以有效,是因为EF在运行时生成一个新的类定义,该类定义继承自您的类定义,并覆盖所有虚拟属性。