简体   繁体   English

在C#应用程序中使用LINQ to SQL的最佳实践方法是什么? [设计模式]

[英]What is the best-practice way to use LINQ to SQL in a C# application? [Design-pattern]

OK, I'm always trying to improve the way I code, because it's my passion. 好吧,我总是试图改进我编码的方式,因为这是我的热情。 I have a .dbml file ( LINQ to SQL ), and I use it to access my SQL Server database. 我有一个.dbml文件( LINQ to SQL ),我用它来访问我的SQL Server数据库。

Imagine, if you will, that you have a Person table in your database and you want to provide a way to delete, add, and modify a Person record. 想象一下,如果您愿意,您的数据库中有一个Person表,并且您希望提供一种删除,添加和修改Person记录的方法。

The way I'm handling things currently is creating classes called PersonRepository, CarRepository, DocumentRepository, etc. For each table in my database, I create a repository class. 我正在处理事物的方式是创建名为PersonRepository,CarRepository,DocumentRepository等的类。对于我的数据库中的每个表,我创建了一个存储库类。

These repository classes generally consist of something similar to this: 这些存储库类通常包含类似于此的内容:

MyDatabaseContext db = new MyDatabaseContext();

public Person GetPersonByID(int id)
{
    return db.Person.Where(p => p.ID == id);
}

Pretty much the same for the basic CRUD functionality of each table. 每个表的基本CRUD功能几乎相同。

If I need something more specific, for example "Sergio, I need a list of all people born between x and y"; 如果我需要更具体的内容,例如“塞尔吉奥,我需要列出所有在x和y之间出生的人”; then I just add the method to the PersonRepository class. 然后我只是将方法添加到PersonRepository类。

public List<Person> GetPeopleFromDOB(DateTime x, DateTime y)
{
    // Do the logic here.
}

Another idea I had was to create a DataAccess.cs class and have all of these methods in there (we would be talking around 4-5 methods per tables in existence) and have them divided by regions. 我的另一个想法是创建一个DataAccess.cs类,并在其中包含所有这些方法(我们将讨论现有的每个表4-5个方法)并按区域划分它们。

What are the more knowledgeable programmers doing and what suggestions would you offer for an eager young programmer (I'm 20 years old)? 什么是知识渊博的程序员正在做什么,你会为一个热切的年轻程序员(我20岁)提供什么建议?

Here are the problems with what you're doing above: 以下是您正在做的事情的问题:

Using List when you should be using IQueryable 在使用IQueryable时使用List

Why use AsQueryable() instead of List()? 为什么使用AsQueryable()而不是List()?

Basically, you should never get data until you need it. 基本上,在您需要之前,您永远不应该获取数据。 With your approach you're always getting data from the database and subsequent LINQ queries will act on all data. 使用您的方法,您总是从数据库获取数据,随后的LINQ查询将对所有数据起作用。 Why not just build up queries and let LINQ refine things down to where it only gets what you need and only when you need it? 为什么不只是构建查询,让LINQ将事情细化到只有你需要的东西,并且只在你需要的时候呢?

Using Methods when Extension Methods would be perfect 扩展方法完善时使用方法

You are creating a utility class of methods with things like GetPeopleFromDOB. 您正在使用GetPeopleFromDOB之类的东西创建一个实用程序类。 Why not make this an Extension method? 为什么不把它作为一个扩展方法? If you make all of them return IQueryable you could use them in succession as well. 如果你让所有这些都返回IQueryable,你也可以连续使用它们。 Eg GetPeople().StatusEnabled().BornInJuly().AgeIsGreaterThan( 57 ); 例如GetPeople().StatusEnabled().BornInJuly().AgeIsGreaterThan( 57 ); Also, if you must do this at least consider doing so in a partial class or a static utility class. 此外,如果必须这样做,至少应考虑在部分类或静态实用程序类中执行此操作。

Consider Using ActiveRecord/Repository Pattern as the root 考虑使用ActiveRecord / Repository Pattern作为根

http://compiledexperience.com/blog/posts/Implementing-an-ActiveRecord-pattern-in-Linq-to-SQL http://compiledexperience.com/blog/posts/Implementing-an-ActiveRecord-pattern-in-Linq-to-SQL

Right now you're creating several hardcoded repositories, but you should be basing them off of Repository? 现在你正在创建几个硬编码的存储库,但是你应该将它们从存储库中删除?

Why not use validators? 为什么不使用验证器?

If you're using ASP.NET MVC, validation is part and parcel, however with webforms you can also use the Data Annotation Validators. 如果您正在使用ASP.NET MVC,则验证是部分和包裹,但是对于webforms,您也可以使用数据注释验证器。

http://adventuresdotnet.blogspot.com/2009/08/aspnet-webforms-validation-with-data.html http://adventuresdotnet.blogspot.com/2009/08/aspnet-webforms-validation-with-data.html

I'd stick with the single responsibility principle and stick with your repository classes. 我坚持单一责任原则并坚持使用您的存储库类。 If your database grows over time, imagine how big the DataAccess class could become. 如果您的数据库随着时间的推移而增长,请想象DataAccess类有多大。 You'll get away with it for a while, but it will grow and grow to the point where you have thousands of lines of code in a class (I have seen 15000+ lines in such a class before) and you're stuck! 你会在一段时间内侥幸成功,但它会增长并发展到你在一堂课中有数千行代码的地步(我之前在这样的课程中已经看到了15000多行)并且你被卡住了!

You'll want to use a repository to connect directly with your DBML using L2S. 您将希望使用存储库使用L2S直接与DBML连接。

Then you'll want to create a service that talks to your repository. 然后,您将需要创建与存储库对话的服务

Finally you'll use the service in things like your code-behind or your MVC controller. 最后,您将在代码隐藏或MVC控制器等事务中使用该服务。

User Repository 用户存储库

Namespace Data

#Region "Interface"
    Public Interface IUserRepository
        Function GetAllUsers() As IList(Of User)
        Function GetUserByID(ByVal id As Integer) As User
    End Interface
#End Region

#Region "Repository"
    Public Class UserRepository : Implements IUserRepository
        Private dc As MyDataContext
        Public Sub New()
            dc = New MyDataContext
        End Sub

        Public Function GetAllUsers() As System.Collections.Generic.IList(Of User) Implements IUserRepository.GetAllUsers
            Dim users = From u In dc.Users
                        Select u
            Return users.ToList
        End Function

        Public Function GetUserByID(ByVal id As Integer) As User Implements IUserRepository.GetUserByID
            Dim viewUser = (From u In dc.Users
                       Where u.ID = id
                       Select u).FirstOrDefault
            Return viewUser
        End Function

    End Class
#End Region
End Namespace

User Service 用户服务

Namespace Data

#Region "Interface"
    Public Interface IUserService
        Function GetAllUsers() As IList(Of User)
        Function GetUserByID(ByVal id As Integer) As User
    End Interface
#End Region


#Region "Service"
    Public Class UserService : Implements IUserService

        Private _ValidationDictionary As IValidationDictionary
        Private _UserRepository As IUserRepository

        Public Sub New(ByVal validationDictionary As IValidationDictionary, ByVal UserRepository As IUserRepository)
            _ValidationDictionary = validationDictionary
            _UserRepository = UserRepository
        End Sub

        Public Function GetAllUsers() As System.Collections.Generic.IList(Of User) Implements IUserService.GetAllUsers
            Return _UserRepository.GetAllUsers
        End Function


        Public Function GetUserByID(ByVal id As Integer) As User Implements IUserService.GetUserByID
            Return _UserRepository.GetUserByID(id)
        End Function

    End Class
#End Region
End Namespace

Now just make sure to use CRUD like you mentioned above. 现在只需确保使用上面提到的CRUD

Also, please forgive my VB. 另外,请原谅我的VB。 You might need to run it through the http://converter.telerik.com code converter to get the C# stuff. 您可能需要通过http://converter.telerik.com代码转换器运行它以获取C#内容。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 C#继承设计模式问题 - C# inheritance design-pattern question C#继承最佳实践 - C# Inheritance best-practice 在 Team Build 中,自动构建使用 VB6 库的 C# 应用程序的最佳实践方法是什么? - In Team Build, what's the best-practice way of automatically building a C# app that uses a VB6 library? 你会如何在C#中实现“特质”设计模式? - How would you implement a “trait” design-pattern in C#? 用嵌套字典编写这样一个条目的最佳、更实用的方法是什么? 使用哪种设计模式? C# - What is the best, more practical way to write such an entry with nested dictionaries? Which design pattern to use? C# 在C#中设计全屏应用程序的最佳方法是什么? - What's the best way to design a full screen application in C#? 是否有应用程序国际化的最佳实践方法? - Is there a best-practice approach for internationalization of an application? 多线程设计模式 - Multithreading design-pattern 在 C# 和 sql 中管理应用程序用户选项的最佳方法是什么? - what is the best way to manage application user options in C# and sql? 使用Selenium PageObject设计模式的最佳方法是什么 - What's the best way to use Selenium PageObject Design Pattern
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM