简体   繁体   English

Code-First或Database-First,如何选择?

[英]Code-First or Database-First, how to choose?

Let us suppose we are going to start new project - application that contains some business logic, user interface on ASP.NET, WPF or both of them. 让我们假设我们将开始新项目 - 包含一些业务逻辑的应用程序,ASP.NET,WPF或两者的用户界面。 We'd like to use ORM or DAL code generator and implement our business logic in .NET classes. 我们想使用ORM或DAL代码生成器并在.NET类中实现我们的业务逻辑。 There are several fundamental ways how we can express our ideas of business domain: 我们可以通过几种基本方式表达我们对业务领域的看法:

  • Implement business classes on .NET and let ORM generate appropriate database schema 在.NET上实现业务类,让ORM生成适当的数据库模式
  • Create database schema manually and generate .NET classes by code generator 手动创建数据库模式并通过代码生成器生成.NET类
  • Use some kind of visual designer, that can generate business classes and database structure or script 使用某种可视化设计器,可以生成业务类和数据库结构或脚本

What do you prefer to write: "Create Table Persons ( ... )" or "public class Person { ... }"? 你更喜欢写什么:“创建表人(...)”或“公共类人{...}”?
What are Pros and Cons of those ways? 这些方式的优点和缺点是什么?
Maybe there are some special situations where one way is better than another? 也许有一些特殊的情况,一种方式比另一种更好?
How to choose optimal way in a particular project? 如何在特定项目中选择最佳方式?

I am quite familiar with "Code-First" (or "Model-First") way, but it seems most of ORMs are designed as code generators or mappers, that suppose that I will manually implement both database structure and business classes. 我对“Code-First”(或“Model-First”)方式非常熟悉,但似乎大多数ORM都设计为代码生成器或映射器,假设我将手动实现数据库结构和业务类。

Answers based on expirience and examples of ORM's are especially welcome. 基于expirience的答案和ORM的例子特别受欢迎。

Edit: Note, the question is not "What should I do first when starting new project?", but "What should be manually declared / automatically generated, domain classes or database structure?" 编辑:注意,问题不是“在开始新项目时我应该先做什么?”,但“应该手动声明/自动生成什么,域类或数据库结构?”

I think the appropriate approach to system analysis and design is to start by modeling your objects and the relations between them first. 我认为系统分析和设计的适当方法是首先建模对象及其之间的关系。 If you're creating a library system you should think of the phrases Book, Author, Publisher, ISBN as objects not as database tables or attributes. 如果您正在创建一个库系统,您应该将短语Book,Author,Publisher,ISBN视为对象,而不是数据库表或属性。 I believe this is the way it should be. 我相信这是应该的方式。 That been said, let's admit that code generators save way a lot of time, and those require a relational database in order to generate the model and map it to the DB objects. 话虽这么说,让我们承认代码生成器节省了很多时间,而那些需要关系数据库才能生成模型并将其映射到数据库对象。 I think this is the major reason why developers tend to start by the DB What could prove my point more is that code generators developers is trying hard to reverse the currently implemented operation (ie You provide a business model-objects and classes- and the generator creates the DB with the appropriate schema for this). 我认为这是开发人员倾向于从数据库开始的主要原因什么可以证明我的观点更多是代码生成器开发人员正在努力扭转当前实现的操作(即,您提供业务模型 - 对象和类 - 以及生成器为此创建具有适当模式的数据库)。

Edit: 编辑:
Here's an example of domain-first generators (ADO.NET Entity Framework itself) Model First : 这是域优先生成器(ADO.NET实体框架本身)模型的示例:

Visual Studio 2010 has to ability to generate a DDL and create a database to store the entity data model. Visual Studio 2010必须能够生成DDL并创建数据库以存储实体数据模型。 The developer has complete control over the entire process being able to customize the DDL, or to select the database he desires, or fine tune the mapping process. 开发人员可以完全控制整个过程,可以自定义DDL,或者选择他想要的数据库,或者微调映射过程。

Why not interface-first? 为什么不先接口?

Too many apps start with a program-first mentality. 太多的应用程序以程序优先的心态开始。 That's a bad idea. 这是个坏主意。 Programming is the heaviest component of building an app, meaning it's the most expensive and hardest to change. 编程是构建应用程序最重要的组成部分,这意味着它是最昂贵且最难改变的。 Instead, start by designing first. 相反,首先要先设计。

Design is relatively light. 设计相对较轻。 A paper sketch is cheap and easy to change. 纸质草图便宜且易于更改。 html designs are still relatively simple to modify (or throw out). HTML设计仍然比较容易修改(或丢弃)。 That's not true of programming. 编程并非如此。 Designing first keeps you flexible. 先设计让您保持灵活性。 Programming first fences you in and sets you up for additional costs. 编程首先围绕您,并为您安排额外费用。

This is from Chapter 9 of Getting Real by 37signals. 这是来自37signals的Get Real第9章

“Show me your flowcharts and conceal your tables, and I shall continue to be mystified. “告诉我你的流程图并隐藏你的桌子,我将继续神秘化。 Show me your tables, and I won't usually need your flowcharts; 告诉我你的桌子,我通常不需要你的流程图; they'll be obvious.” 他们会很明显。“

— Fred Brooks in “The Mythical Man-Month” - 弗雷德布鲁克斯在“神话人月”

In my opinion there is no correct answer to this. 在我看来,没有正确的答案。 I guess it mostly boils down to your own personal or your teams preferences. 我想这主要归结为你个人或团队的偏好。 All mentioned approaches (database first, code first, interface first) have their own advantages and disadvantages. 所有提到的方法(数据库优先,代码优先,接口优先)都有各自的优缺点。

I'd probably sit down with pen and paper and sketch up the general structure and the main functions of the application before i do anything specific, be it code or database tables. 在我做任何特定的事情之前,我可能会用笔和纸坐下来勾勒应用程序的一般结构和主要功能,无论是代码还是数据库表。 A simple drawing of the basic user interface also helps a lot. 基本用户界面的简单绘图也有很大帮助。

Analysis of requirements first, and then some documentation of those needs and an overview of the data aspects of this? 首先分析需求,然后对这些需求进行一些记录并对数据方面进行概述?

Then you know what data you'll be capturing and how it relates to other data, and can design a database schema or data structure to match it (as logical objects/tables of related content, not "tab1_data", "tab2_data" matching the data capture process which could change, but you know that!). 然后你知道你将捕获哪些数据以及它与其他数据的关系,并且可以设计数据库模式或数据结构以匹配它(作为相关内容的逻辑对象/表,而不是“tab1_data”,“tab2_data”匹配数据捕获过程可能会改变,但你知道!)。 You could even design a .xsd first and generate code and a database schema from that. 你甚至可以先设计一个.xsd,然后从中生成代码和数据库模式。 It's all fun and games these days, depending on your skillset. 这些天都很有趣,这取决于你的技能。

As the database schema in my mind stores the data, and that is the really important thing for a business to have, I would design that first - multiple tools may access it in time, maybe the original system would be replaced down the line (eg, migration to newer tools/languages/interfaces). 由于我脑海中的数据库模式存储数据,这对于企业来说非常重要,我会先设计 - 多个工具可以及时访问它,也许原始系统会被替换掉(例如,迁移到更新的工具/语言/接口)。 If you know nothing about database theory, then maybe that's not your best option but I would still get any generated schema verified by someone else. 如果您对数据库理论一无所知,那么这可能不是您的最佳选择,但我仍然会得到其他人验证的任何生成的模式。

In most cases it won't matter much. 在大多数情况下,它并不重要。 It is more up to personal preference and skill than anything else. 这取决于个人偏好和技能,而不是其他任何东西。 Most apps are not going to suffer much either way, use whatever your team is comfortable with. 大多数应用程序不会受到任何影响,使用您的团队所熟悉的任何内容。 Where the choice really matters it should be obvious which approach to go for. 选择真正重要的地方应该明确哪种方法。

That said, my personal opinion is that "database first" is generally the safer choice. 也就是说,我个人认为“数据库优先”通常是更安全的选择。 If the data is in any way important, especially if it is important outside the scope of your particular app, you want to have full control over how it is stored. 如果数据在任何方面都很重要,特别是如果数据在特定应用程序范围之外很重要,那么您希望完全控制数据的存储方式。

"Code first" (implied: leaving the database in the hands of some automatic tool) is in my mind really a shortcut, one you should use when (and only when) you know for sure you can get away with it. “代码优先”(暗示:将数据库留在一些自动工具的手中)在我的脑海里真的是一个快捷方式,你应该使用的时候(并且只有当你知道)你可以侥幸逃脱它。

To answer your edited question (manual db/auto classes or manual classes/db), I'd choose "neither". 要回答你编辑过的问题(手动db / auto classes或manual classes / db),我选择“both”。 Autogenerated code of both kinds are to be avoided for a number of reasons, first of all YAGNI. 出于多种原因,首先要避免两种类型的自动生成代码,首先是YAGNI。 You end up with code you never wrote but are nonetheless responsible for, code you'll never use, and (in my experience) code you'll end up spending more time refactoring than if you'd designed and written it yourself in the first place. 你最终得到了你从未写过的代码,但仍然负责,你永远不会使用的代码,以及(根据我的经验)代码,你最终会花费更多的时间进行重构,而不是你自己设计和编写的代码。地点。 And they both keep your focus far away from the most important location - the User. 而且他们都将焦点远离最重要的位置 - 用户。

Domain modelling vs relational modelling 域建模与关系建模

There are several fundamental ways how we can express our ideas of business domain 我们可以通过几种基本方式表达我们的业务领域

I think it is important to first establish that the domain is independent of concrete technologies and/or programming paradigms (eg OO, FP, relational). 我认为首先确定域独立于具体技术和/或编程范例(例如OO,FP,关系)是很重要的。 This answer will assume you've already separately defined your domain, eg using DDD practices, and now wish to use a relational database to store it. 这个答案将假设您已经单独定义了您的域,例如使用DDD实践,现在希望使用关系数据库来存储它。

Relational model strengths 关系模型的优势

The relational model was invented, among other reasons, to do away with the many problems that were caused by previous models, including the networked model (which includes OO models), the hierarchical model (which includes XML/JSON models), or simple key value stores. 除了其他原因之外,发明了关系模型,以消除由先前模型引起的许多问题,包括网络模型 (包括OO模型), 分层模型 (包括XML / JSON模型)或简单密钥超值商店。 It has a lot of strengths over all alternatives, which has made it so popular for decades. 它在所有替代方案上都有很多优势,这使它几十年来如此受欢迎。

In my opinion, these strengths indicate that you should design your database model inside of the database, which has been made for precisely that purpose. 在我看来,这些优势表明,你应该设计的数据库,该数据库已经取得了正是为此目的的内部数据库模型。 All other models, including your client model, are copies of that original , relational model from within the database. 所有其他模型(包括客户端模型)都是数据库中原始关系模型的副本。 Thus, all other models should be derived from it, not source for it. 因此,所有其他模型都应该来自它,而不是它的来源

See the relational model, expressed in DDL, as your source of truth 请参阅以DDL表示的关系模型作为您的真实来源

XSD is the same XSD是一样的

XML/XSD is a similar technology. XML / XSD是一种类似的技术。 Your data is expressed in terms of XML, but when two systems communicate with each other through an XML based API, XSD (or eg WSDL if you want) is the most appropriate language to specify that communication. 您的数据以XML表示,但当两个系统通过基于XML的API相互通信时,XSD(或WSDL,如果您需要)是指定该通信的最合适的语言。

If you want to to bind to your XML documents using client technology, eg JAXB in Java, then you should generate those JAXB classes from the XSD, not vice versa. 如果您想使用客户端技术(例如Java中的JAXB)绑定到XML文档,那么您应该从XSD生成这些JAXB类,而不是相反。 Why? 为什么? Because XSD is the source of truth 因为XSD是事实来源

I've written about this topic here . 我在这里写过这个主题

Start by not directly thinking about either, rather "model" (preferably on paper) what parts your application will have from the users point of view. 首先,不要直接考虑任何一种,而是“模型”(最好在纸上)从应用程序的角度来看应用程序将具有哪些部分。

If you have a clear mental picture of that model, You can divide the parts up in common and specific little elements which you can translate to both object definitions and database tables. 如果您对该模型有清晰的心理图像,则可以将这些部分分成共同的特定小元素,您可以将它们转换为对象定义和数据库表。

I find this method to cut database normalization time and effort significantly. 我发现这种方法可以显着缩短数据库规范化时间和精力。

Personally I like control over creating RDBMS objects. 就个人而言,我喜欢控制创建RDBMS对象。 When I use the EF code first, it actually created more work for basic things such as table relations etc. which most decent code generators does for you out of the box ( I know thats the idea ... more control on your Models!). 当我首先使用EF代码时,它实际上为基本的东西创建了更多的工作,例如表关系等,大多数不错的代码生成器为你开箱即用(我知道这个想法......更多控制你的模型!) 。 Also the Idea that EFCF will generate the db as I am hoping for is a bit scary. 另外,我希望EFCF会生成数据库的想法有点可怕。 (traditionally Code evolves more easily then RDMBS!) (传统上Code比RDMBS更容易发展!)

For a system which required constant evolving (for eg SaaS), and usually a large Enterprise Level system with 500 + tables etc, its can be less attrative proposition. 对于需要不断发展的系统(例如SaaS),以及通常具有500 +表等的大型企业级系统,其可能不那么吸引人的主张。 On the other hand if you have a proper SQL Server 2008 database project with all the tables,SP,Triggers, Indexes scripted and you can deploy them from the Visual Studio it much more managble. 另一方面,如果您有一个适当的SQL Server 2008数据库项目,其中包含所有表,SP,触发器,索引脚本,并且您可以从Visual Studio部署它们,那么它就更容易管理。 You now have freedom of using any codegen you want for your tables (even build your own) 您现在可以自由地使用您想要的任何代码表(甚至构建自己的代码)

You are not tied to the on Framework (EFCF) you can then use different ORMs (NHibernet for eg) depending upon your 'mini' project requirement in your large system. 您不依赖于框架(EFCF),然后您可以使用不同的ORM(例如NHibernet),具体取决于您的大型系统中的“迷你”项目要求。

There are 3 important aspects that need to be considered when developing a database application... 在开发数据库应用程序时需要考虑3个重要方面......

  1. User Experience 用户体验
  2. Data Quality 数据质量
  3. Cost to maintain the first two (User Experience, and Data Quality) 维持前两个的成本(用户体验和数据质量)

I believe the priority of these three items are expressed in the order they are presented, meaning the highest priority is User Experience, the second highest priority is data quality, and the third is the cost to do so. 我相信这三个项目的优先级以它们的呈现顺序表示,这意味着最高优先级是用户体验,第二个优先级是数据质量,第三个是这样做的成本。 Of course these can be debated, but the notion of code first or database first is relative to the third priority - the cost. 当然这些可以辩论,但首先是代码或数据库的概念是相对于第三优先级 - 成本。 Whatever the choice is - code first or database first, ensure the first two priorities are fulfilled... 无论选择什么 - 首先是代码或首先是数据库,确保满足前两个优先级......

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

相关问题 DbContext生命周期在数据库优先和代码优先的应用程序开发中的重要性 - Importance of the lifetime of the DbContext in database-first & code-first application development 实体框架代码优先:如何手动更新数据库? - Entity Framework Code-First: How to manually update the database? 首先在Entity Framework中恢复数据库代码 - Revert database in Entity Framework code-first EntityFramework 6基于数据库的连接字符串的基于代码的配置 - EntityFramework 6 Code-based configuration of connection string for database-first 实体框架 - 加入方法 - 混合代码优先和数据库优先 - Entity Framework - Joining approaches - Mixing code-first and database first EF Code-first:如何缓存DbCompiledModel? - EF Code-first: how to cache DbCompiledModel? 如何使用EF数据库中的存储过程填充DataTable - How to populate DataTable using stored procedure in EF database-first 代码优先:将实体映射到现有数据库表 - Code-first: Mapping entities to existing database tables 使用Entity Framework 4和Code-First从数据库中排除字段/属性 - Exclude a field/property from the database with Entity Framework 4 & Code-First 手动更新由EF代码优先创建的数据库模式 - Manually updating a database schema created by EF code-first
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM