Übersetzung vorschlagen
 
Andere Vorschläge:

progress indicator
Keine anderen Vorschläge
MSDN Magazin > Home > Ausgaben > 2009 > MSDN Magazin August 2009 >  EF Datenzugriff: EF v2 und Datenzugriffsarchite...
Inhalt anzeigen:  Englisch mit deutscher ÜbersetzungInhalt anzeigen: Englisch mit deutscher Übersetzung
Dies sind maschinell übersetzte Inhalte, die von den Mitgliedern der Community bearbeitet werden können. Sie können die Übersetzung verbessern, indem Sie auf den jeweils zum Satz gehörenden Link "Bearbeiten" klicken.Mithilfe des Dropdown-Steuerelements "Inhalt anzeigen" links oben auf der Seite können Sie zudem bestimmen, ob nur der englische Originaltext, nur die deutsche Übersetzung oder beides nebeneinander angezeigt werden.
EF Data Access
EF v2 and Data Access Architecture Best Practices
Tim Mallalieu

This article discusses:
  • Application development styles
  • Design patterns
This article uses the following technologies:
Microsoft Visual Studio 2010, ADO.NET Entity Framework Feature CT1
David Hill, in his preface to the latest patterns & practices Architecture Guidance, jokes that the key to being a good architect is learning to answer "It depends" to most questions. In this article, I'll take that joke to heart. How can you use the Entity Framework with your application architecture? Well, it depends.
Developers deploy a wide variety of development philosophies and architecture styles. This article explores three common perspectives on application development and describes how the Entity Framework can be employed in each. Specifically, I'll look at the forms-centric, model-centric, and code-centric development styles and their relationship to the Entity Framework.

Application Development Styles
I'll start with a discussion of the various development styles. This discussion does not make strong assumptions about particular methodologies that can be applied within these development styles, and I should note that I've used stereotypes for the purpose of this article. Most development styles blend elements of the models I describe. Figure 1 shows the relative characteristics of the models I'll discuss.
Figure 1 Development Styles and Their Associated Tradeoffs
Forms-Centric. In the forms-centric (or "forms-over-data") style of development, the focus is largely on the construction of the top-level user interface (UI) elements that bind to data. The Microsoft development experience for this style is often a drag-and-drop experience in which you define a data source and then systematically construct a series of forms that can perform create, read, update, and delete (CRUD) operations on the underlying data source. This experience tends to be highly productive and intuitive for a developer. The cost is often that the developer accepts a fairly high degree of prescription from the tools and frameworks being used.
Model-Centric. Model-centric development is a step beyond the forms-centric approach. In model-centric development, a developer defines a model in a visual tool or some textual domain-specific language (DSL) and uses this model as the source for generating classes to program against and a database for persistence. This experience is often handy for tools developers who want to build on existing infrastructure to deliver added value. It is also often useful for organizations that want to prescribe their own standards for their application architectures and databases. The cost of this path has historically been in the investment required to enable a complete experience. As with the forms-centric experience, a developer leveraging a model-centric experience tends to give up some flexibility as a consequence of operating in a more prescribed world.
Code-Centric. In the code-centric application development style, the truth is the code. Developers define persistent classes on their own. They elect to write their own data access layer to support these classes, or they use some available persistence offering to do this for them. The main benefit of the code-centric option is that developers get the utmost flexibility. The cost consideration tends to fall on the approach chosen for persistence. If a developer selects a solution that allows her to focus on the business domain instead of the persistence infrastructure, the overall benefit of this approach can be very high.

Building a Forms-Centric Application
In this section, I'll walk through how to build a very simple application using the forms-centric approach with the Entity Framework. The first step is to create a Visual Studio project. For this example, I created a Dynamic Data application. In Visual Studio 2010, you select the Dynamic Data Entities Web Application, as shown in Figure 2.
Figure 2 Visual Studio 2010 New Project dialog box with Dynamic Data Entities Web Application project template selected.
The next step is to specify the Entity Framework as a data source for the application. You do this by adding a new ADO.NET Entity Data Model project item to the project, as you can see in Figure 3.
Figure 3 Add New Item Dialog Box with ADO.NET Entity Data Model Project Item Selected
After selecting this project item, you perform the following three steps:
  1. Choose to start from a database.
  2. Choose the database to target.
  3. Select the tables to import.
At this point, you click Finish and see the model that is generated from the database, as shown in Figure 4.
Figure 4 Default Entity Data Model Created from the Northwind Database
Now that the model has been generated, using it in the Dynamic Data application is as simple as configuring the form to register the object context that was created in the steps performed earlier. In Global.asax.cs, you can modify the following code to point to the context:
DefaultModel.RegisterContext(typeof(NorthwindEntities), new   ContextConfiguration() 
    { ScaffoldAllTables = true});
You should now be able to run your application and have a functional set of forms over your persistent data, as shown in Figure 5.
Figure 5 Default Dynamic Data Site Using the Entity Framework
This exercise illustrates the most straightforward forms-driven experience. You can now start working on how the presentation should look and what behaviors you need. The ASP.NET Dynamic Data framework uses CLR attributes in the System.ComponentModel.DataAnnotations namespace to provide guidance on how data can be rendered. For example, you can change how the form is rendered by adding an annotation that hides a particluar column. The attribute is as follows:
[ScaffoldColumn(false)]
The ScaffoldColumn attribute indicates whether the Dynamic Data framework renders the column. In a case where a table is to be rendered, you can use the ScaffoldColumn attribute to opt out of rendering a specific column. The interesting challenge in the current scenario is where and when do you attribute a column? In this example, the CLR classes, which are used by Dynamic Data, were generated from the Entity Data Model. You can attribute the generated classes, but then any changes to the model will cause the loss of the attributes. Dynamic Data also allows you to apply attributes by using partial classes associated with your entities class, but then you lose some readability and discoverability because of the loss of encapsulation.
Entity Framework 4.0 will provide an extensibility model that allows developers to extend the Entity Framework Designer's tooling surface and add additional metadata that can then be used in code or database generation; however, this functionality is not available in Visual Studio 2010 beta 1.
The Entity Framework developer who wants to work with Dynamic Data can have a very productive experience. He can start with a database and annotate a model with the appropriate metadata to drive much of that experience. After the model is in good shape, the developer can focus on the UI. For more information on using Dynamic Data with the Entity Framework, please take a look at the official Dynamic Data Web site.

Thoughts on Forms-Centric Applications
Using ASP.NET Dynamic Data and the Entity Framework provides a highly productive experience for developing data-centric applications. However, forms-centric applications are not local to Dynamic Data. Many UI-first development experiences that allow developers to build an application by creating a set of screens over a data source tend to share the same characteristics. The developer experience generally relies on some combination of design-time and run-time experiences that prescribe a given architectural style. The data model often reflects the shape of the persistent store (the underlying tables), and there is often a fair bit of UI metadata (such as DataAnnotations in the case of Dynamic Data) that help to define the UI.
The role of the Entity Framework within a forms-centric experience is primarily as the abstraction over the underlying data source. The extensibility capabilities give a developer one true place to define all the model metadata that they need to express. The mapping capabilities allow a developer to reshape the mid-tier domain classes declaratively without having to dive down into infrastructure code.

Building a Model-Centric Application
The promise of model-driven development is that developers can declaratively express a model that is closer to the conceptual business domain than the run-time concerns of a given application architecture. For the purpose of this article, I've focused on the experience of having a single design surface on which you define the domain and related metadata and from which you provision classes and storage.
In the Microsoft .NET Framework 4, there are a number of innovations in Entity Framework tooling that enable a model-centric experience. Entity Framework tooling provides a basic experience plus the capabilities for framework developers, ISVs, and IT organizations to extend those capabilities. To illustrate the experience, I'll walk through a simple application.
I'll start with a new Dynamic Data project again and add an ADO.NET Entity Data Model project item. This time, however, I'll start with a blank model rather than create the model from a database. By starting with a blank surface, you can build out the model you want. I'll build a very simple Fitness application with just two entity types, Workout and WorkoutType. The data models for the types are shown in Figure 6.
Figure 6 Simple Entity Data Model
When you define a model like this in the Entity Framework Designer, there is no mapping or store definition created. However, the Entity Framework Designer now allows developers to create a database script from this model. By right-clicking the designer surface, you can choose Generate Database Script From Model, as shown in Figure 7, and the Entity Framework Designer generates a default database from the entity model. For this simple model, two tables are defined. The names of the tables match the EntitySets that are defined in the designer. In the default generation, the database created will build join tables for many-to-many relationships and employ a Table Per Type (TPT) scheme for building tables that must support an inheritance hierarchy.
Figure 7 Generating a Database Script from the Model
When you invoke Generate Database Script from Model, a new T-SQL file is added to the project and the Entity Data Model you've created provides the Entity Framework metadata with valid mapping and store descriptions. You can see these in Figure 8.
Figure 8 The T-SQL File Generated from the Model
If a developer is using Visual Studio Team Architect or Team Suite, she can deploy and execute the T-SQL script within Visual Studio merely by clicking in the T-SQL file to give it focus and then pressing F5. You are prompted to select the target database, and then the script executes.
At the same time, the Entity Framework Designer runs the default code generation to create classes based on the model, the Entity Framework artifacts required to describe the mapping between the model and the database, and a description of the data store that was created. As a result, you now have a strongly typed data access layer that can be used in the context of your application.
At this point, you've seen only the default experience. The Entity Framework Designer's extensibility allows you to customize many aspects of the model-driven experience. The database-generation and code-generation steps use T4 templates that can be customized to tailor the database schema and the code that is produced. The overall generation process is a Windows Workflow Foundation (WF) workflow that can also be customized, and you have already seen how you can add extensions to the tools surface by using Managed Extensibility Framework–based Visual Studio extensibility. As an example of this extensibility, let's look at how you can change the code-generation step in the project.
By right-clicking the design surface, you can choose Add New Artifact Generation Item. Choosing this command opens a dialog box in which you can select any of the installed templates to add to the project. In the example shown in Figure 9, I selected the Entity Framework POCO Code Generator template (Note: The POCO template does not work with Dynamic Data in Visual Studio 2010 beta 1, but it will work in upcoming releases.) POCO (Plain Old CLR Objects) classes allow developers to define only the items they care about in their classes and avoid polluting them with implementation details from the persistence framework. With .NET 4.0, we have introduced POCO support within the Entity Framework, and one way of creating POCO classes when you are using a model-centric or data-centric development style is with the use of the POCO template. The POCO template is currently available in the ADO.NET Entity Framework Feature CTP 1, which can be downloaded from Data Platform Development and used with Visual Studio 2010 beta 1.
Figure 9 Add New Item Dialog Box
By selecting the ADO.NET EF POCO Code Generator template, you get a different set of generated classes. Specifically, you get a set of POCO classes generated as a single file per class, a helper class to use for changes to related items, and a separate context class. Note that you did not do anything to the model. You merely changed the code-generation template.
One interesting capability added in .NET 4.0 is the capability to define functions in terms of the Entity Data Model. These functions are expressed in the model and can be referenced in queries. Think about trying to provide a method to determine how many calories are burned in a given workout. There is no property defined on the type that captures the calories burned. You could query the existing types and then enumerate the results, calculating the calories burned in memory; however, by using model-defined functions, you can fold this query into the database query that is sent to the store, thus yielding a more efficient operation. You can define the function in the EDMX (XML) as follows:
<Function Name="CaloriesBurned" ReturnType="Edm.Int32">
    <Parameter Name="workout" Type="Fitness.Workout" />
    <DefiningExpression>
        workout.Duration * workout.WorkoutType.CaloriesPerHour / 60
    </DefiningExpression>
</Function>
To allow this function to be used in a LINQ query, you need to provide a function in code that can be leveraged. You annotate this method to indicate which model function you intend to use. If you want the function to work when directly invoked, you should implement the body. For the purpose of this exercise, we will throw an unsupported exception because we expect to use this function in the form of LINQ queries that will be pushed to the store:
        [EdmFunction("Fitness", "CaloriesBurned")]
        public int CaloriesBurned(Workout workout) 
               { throw new NotSupportedException(); }
If you want to then build a query to retrieve all high-calorie workouts, where a high-calorie workout is greater than 1,000 calories, you can write the following query:
    var highCalWorkouts = from w in context.MyWorkouts
                          where
                          context.CaloriesBurned(w) > 1000
                          select w;
This LINQ query is a valid query that can now leverage the CaloriesBurned function and be translated to native T-SQL that will be executed in the database.

Thoughts on Model-Centric Application Development
In the degenerate case, where a developer uses the model-first experience and does not customize any of the steps, the model-centric experience is very much like the forms-centric experience. The model the developer is working with is a higher-level model than the logical data model, but it is still a fairly data-centric view of the application.
Developers who extend their Entity Data Model to express more metadata about their domain and who customize the code and/or database generation can come to a place where the experience approaches one in which you define all the metadata for your runtime. This is great for IT organizations that want to prescribe a strict architecture and set of coding standards. It is also very useful for ISVs or framework developers who want to use the Entity Framework Designer as a starting point for describing the model and then generate a broader end-to-end experience from it.

Code-Centric Application Development
The best way to describe code-centric application development is to cite the cliché "the code is the truth." In the forms-centric approach, the focus is on building a data source and UI model for the application. In the model-centric approach, the model is the truth: you define a model, and then generation takes place on both sides (storage and the application). In the code-centric approach, all your intent is captured in code.
One of the challenges of code-centric approaches is the tradeoff between domain logic and infrastructure logic. Object Relational Mapping (ORM) solutions tend to help with code-centric approaches because developers can focus on expressing their domain model in classes and let the ORM take care of the persistence.
As we saw in the model-centric approach, POCO classes can be used with an existing EDM model (in either the model-first or database-first approaches). In the code-centric approach, we use something called Code Only, where we start with just POCO classes and no other artifacts. Code Only is currently available in the ADO.NET Entity Framework Feature CTP 1, which can be downloaded from Data Platform Development and used with Visual Studio 2010 Beta 1.
Consider replicating the Fitness application using only code. Ideally, you would define the domain classes in code such as shown in Figure 10.
    public class Workout
    {
        public int Id { get; set; }
        public DateTime DateTime { get; set; }
        public string Notes { get; set; }
        public int Duration { get; set; }
        public virtual WorkoutType WorkoutType { get; set; }

    }
    public class WorkoutType
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public int CaloriesPerHour { get; set; }
    }
To make the domain classes work with the Entity Framework, you need to define a specialized ObjectContext that represents the entry point into the Entity Framework (much like a session or connection abstraction for your interaction with the underlying database). The ObjectContext class must define the EntitySets that you can create LINQ queries on top of. Here's an example of the code:
    public class FitnessContext : ObjectContext
    {
        public FitnessContext(EntityConnection connection)
            : base(connection, "FitnessContext")
        {
        }

        public IObjectSet<Workout> Workouts { 
            get { return this.CreateObjectSet<Workout>(); } }

        public IObjectSet<WorkoutType> WorkoutTypes { 
            get { return this.CreateObjectSet<WorkoutType>(); } }
    }
In the code-only experience, a factory class is used to retrieve an instance of the context. This context class reflects over the context and builds up the requisite metadata for the run-time execution. The factory signature is as follows:
ContextBuilder.Create<T>(SqlConnection conn)
For convenience, you can add a factory method to the generated context. You provide a static field for the connection string and a static factory method to return instances of a FitnessContext. First the connection string:
        static readonly string connString = new SqlConnectionStringBuilder
        {
            IntegratedSecurity = true,
            DataSource = ".\\sqlexpress",
            InitialCatalog = "FitnessExpress",
        }.ConnectionString;
And here is the factory method:
        public static FitnessContext CreateContext()
        {
            return ContextBuilder.Create<FitnessContext>(
                                   new SqlConnection(connString));
        }
With this, you have enough to be able to use the context. For example, you could write a method such as the following to query all workout types:
        public List<WorkoutType> AllWorkoutTypes()
        {
            FitnessContext context = FitnessContext.CreateContext();
            return (from w in context.WorkoutTypes select w).ToList();            
        }
As with the model-first experience, it is handy to be able to deploy a database from the code-only experience. The ContextBuilder provides some helper methods that can check whether a database exists, drop it if you want to, and create it.
You can write code like the following to bootstrap a simple set of demo functionality using the code-only approach:
        public void CreateDatabase()
        {
            using (FitnessContext context = FitnessContext.CreateContext())
            {
                if (context.DatabaseExists())
                {
                    context.DropDatabase();
                }
                context.CreateDatabase();
            }
        }
At this point, you can use the Repository pattern from domain-driven design (DDD) to elaborate a bit in what we have seen so far. The use of DDD principles is a common trend in application development today, but I won't attempt to define or evangelize domain driven design here. (For more information, read content from experts such as Eric Evans (Domain-Driven Design: Tackling Complexity in the Heart of Software, Addison-Wesley, 2003) and Jimmy Nilsson (Applying Domain-Driven Design and Patterns: With Examples in C# and .NET, Addison-Wesley, 2006 ).
Currently, we have a handwritten set of domain classes and a specialized ObjectContext. When we used Dynamic Data, we just pointed the framework at the ObjectContext. But if we want to consider a stronger abstraction of our underlying persistence layer, and if we want to truly constrain the contract of operations to just the meaningful domain operations that one should do, we can leverage the Repository pattern.
For this example, I'll define two repositories: one for WorkoutTypes and one for Workouts. When you follow DDD principles, you should think hard about the aggregate root(s) and then think about modeling the repositories appropriately. In this very simple example, I've used two repositories to illustrate high-level concepts. Figure 11 shows the WorkoutType repository, and Figure 12 shows the Workout repository.
    public class WorkoutTypeRepository
    {
         public WorkoutTypeRepository()
         {
              _context = FitnessContext.CreateContext();
         }
         public List<WorkoutType> AllWorkoutTypes()
         {
              return _context.WorkoutTypes.ToList();
         }
         public WorkoutType WorkoutTypeForName(string name)
         {
              return (from w in _context.WorkoutTypes
              where w.Name == name
              select w).FirstOrDefault();
         }
         public void AddWorkoutType(WorkoutType workoutType)
         {
              _context.WorkoutTypes.AddObject(workoutType);
         }
         public void Save()
         {
              this._context.SaveChanges();
         }
         private FitnessContext _context;
    }
    public class WorkoutRepository
    {
        public WorkoutRepository()
        {
            _context = FitnessContext.CreateContext();
        }

        public Workout WorkoutForId(int Id)
        {
            return (from w in _context.Workouts where w.Id == Id select w).FirstOrDefault();
        }

        public List<Workout> WorkoutsForDate(DateTime date)
        {
            return (from w in _context.Workouts where w.DateTime == date select w).ToList();
        }

        public Workout CreateWorkout(int id, DateTime dateTime, int 
                  duration, string notes, WorkoutType workoutType)
        {
            _context.WorkoutTypes.Attach(workoutType);
            Workout workout = new Workout() { Id = id, DateTime = dateTime, Duration = duration,
              Notes = notes, WorkoutType = workoutType };
            _context.Workouts.AddObject(workout);
            return workout;
        }

        public void Save()
        {
            _context.SaveChanges();
        }

        private FitnessContext _context;

    }
One interesting thing to note is that the return types are not IQueryable<T>; they are List<T>. There are debates about whether you should expose IQueryable past the boundaries of the persistence layer. My opinion is that exposing IQueryable breaks the encapsulation of the persistence layer and compromises the boundary between explicit operations that happen in memory and operations that happen in the database. If you expose an IQueryable<T> from the repository, you have no idea who will end up composing a database query in LINQ higher up the stack.
You can now use these repositories to add some data in the store. Figure 13 shows two methods that could be used to create some sample data.
public void AddWorkouts()
{
     Console.WriteLine("--- adding workouts ---");
     WorkoutRepository repository = new WorkoutRepository();
     WorkoutTypeRepository typeRepository = new WorkoutTypeRepository();

     WorkoutType squash = typeRepository.WorkoutTypeForName("Squash");
     WorkoutType running = typeRepository.WorkoutTypeForName("Running");

     repository.CreateWorkout(0,new DateTime(2009, 4, 20, 7, 0, 0),
       60, "nice squash workout", squash);
     repository.CreateWorkout(1, new DateTime(2009, 4, 21, 7, 0, 0),
       180, "long run", running);
     repository.CreateWorkout(2, new DateTime(2009, 4, 22, 7, 0, 0),
       45, "short squash match", squash);
     repository.CreateWorkout(3, new DateTime(2009, 4, 23, 7, 0, 0),
       120, "really long squash", squash);
     repository.Save();
}
In the model-first scenario, we used model-defined functions to provide a method to determine how many calories are burned in a given workout, even though there is no property defined on the type that captures the calories burned. With the code-only approach, you do not have the option to define model-defined functions here. You can, however, compose on top of the existing Workout EntitySet to define a query that already encapsulates the high-calorie filter, as shown here:
        public IQueryable<Workout> HighCalorieWorkouts()
        {
            return (
              from w in Workouts 
               where (w.Duration * w.WorkoutType.CaloriesPerHour / 60) > 1000
                 select w);
        }
If we define this method on the FitnessContext, we can then leverage it in the Workout Repository as follows:
        public List<Workout> HighCalorieWorkouts()
        {
            return _context.HighCalorieWorkouts().ToList();
        }
Because the method on the context returned an IQueryable, you could have further composed on top of it, but I chose, for symmetry, to just return the results as a List.

Thoughts on Code-Centric Development
The code-centric experience is highly compelling for developers who want to express their domain logic in code. The code-centric experience lends itself well to providing a level of flexibility and clarity needed to work with other frameworks. Using abstractions like the Repository pattern, this approach lets developers provide a high degree of isolation for the persistence layer, which allows the application to remain ignorant of the persistence layer.

Final Thoughts on the Application Development Styles
These are the three application development styles that we often see. As mentioned earlier, there is no single, true classification of these development styles. They lie more on a continuum from highly prescriptive, very data-centric and CRUD-centric experiences that focus on productivity, to highly expressive code-centric experiences.
For all of these, the Entity Framework can be leveraged to provide the persistence layer. As you move toward the form-centric and model-centric side of the spectrum, the explicit model and the ability to extend the model and tool chain can help the Entity Framework improve overall developer productivity. On the code-centric side, the improvements in the Entity Framework allow the runtime to get out of the way and be merely an implementation detail for persistence services.

Tim Mallalieu is the product unit manager for the Entity Framework and LINQ to SQL. He can be reached at blogs.msdn.com/adonet.

EF-Datenzugriff
EF v2 und Datenzugriffsarchitektur – bewährte Methoden
Tim Mallalieu

Themen in diesem Artikel:
  • Anwendung Entwicklung Formatvorlagen
  • Entwurfsmuster
In diesem Artikel werden die folgenden Technologien verwendet:
Microsoft Visual Studio 2010 ADO.NET Entity Framework Funktion CT1
David Hill in seinem Vorwort auf die neueste Muster &Empfehlungen Architecture Guidance, Witze, die der Schlüssel wird eine gute Architekt beantworten "Es hängt" lernen istDie meisten Fragen. In diesem Artikel werde ich die Witz Herz dauern. Wie können Sie die Entity Framework mit Ihrer Anwendungsarchitektur? Gut, kommt es.
Entwickler wenden verschiedenste Entwicklungsphilosophien und Architekturstile an. Dieser Artikel untersucht drei allgemeine Perspektiven im Hinblick auf die Anwendungsentwicklung und beschreibt, wie das Entity Framework in jeder davon eingesetzt werden kann. Insbesondere ich betrachten die Formulare zentrierten, Modell zentrierten und Code-zentrierten Entwicklung Formatvorlagen und ihre Beziehung zu den Entity Framework.

Anwendung Development Formatvorlagen
Ich beginne mit einer Erläuterung der verschiedenen Entwicklung Formatvorlagen. Diese Diskussion wird nicht starke Annahmen über bestimmte Methoden, die innerhalb dieser Entwicklung Stile angewendet werden können stellen, und ich beachten, dass Stereotypen zum Zweck der in diesem Artikel verwendet haben. Die meisten Entwicklung Formatvorlagen mischen Elemente die Modelle beschrieben. Abbildung 1 zeigt die relative Merkmale von den Modellen besprochen werden.
Abbildung 1 Development Formatvorlagen und ihre zugeordneten Nachteile
Formulare zentrierte. Der Schwerpunkt liegt im Format Formulare zentrierten (oder "Formulare-über-Data") der Entwicklung größtenteils auf die Konstruktion von der obersten Ebene (UI) Benutzeroberflächenelemente, die an Daten binden. Die Microsoft-Entwicklungsumgebung für diese Formatvorlage ist häufig eine Drag & Drop Funktionalität in dem Sie eine Datenquelle definieren und dann systematisch Konstrukt eine Reihe von Formularen, die ausgeführt werden können erstellen, lesen, aktualisieren und Löschen von Operationen (CRUD) in der zugrunde liegenden Datenquelle. Diese Erfahrung neigt dazu, sehr produktiv und für einen Entwickler intuitiv sein. Die Kosten sind häufig, dass der Entwickler ein relativ hohes Maß an verschreibungspflichtige aus den Tools und Frameworks verwendeten akzeptiert.
Modell zentrierte. Modell-zentrierten Entwicklung ist ein Schritt jenseits der forms-centric Ansatz. In der Model-zentrierten Entwicklung ein Entwickler definiert ein Modell in ein visuelles Tool oder einige textbezogene domänenspezifischen Sprache (DSL) und verwendet dieses Modell als Quelle Generieren von Klassen für Dauerhaftigkeit eine Datenbank zu programmieren. Diese Erfahrung ist häufig nützlich für Entwickler von Tools, die auf vorhandene Infrastruktur zusätzlichen Wert liefern erstellen möchten. Außerdem ist oft nützlich für Organisationen, die eigene Standards für Ihre Anwendungsarchitekturen und Datenbanken vorzugeben. Die Kosten für diesen Pfad wurde in der Vergangenheit in der Kapitalanlage erforderlich, um eine vollständige Funktionalität zu aktivieren. Wie mit der Formulare zentrierten Erfahrung neigt dazu, geben Sie gewisse Flexibilität als Konsequenz der Betrieb in einer mehr vorgeschriebenen Welt ein Entwickler eine Modell-zentrierte Erfahrung nutzen.
Code-zentrierte. Der Code-zentrierte Anwendung Entwicklung Formatvorlage ist die Wahrheit der Code. Entwickler definieren permanente Klassen auf eigene. Sie sich entscheiden, Ihre eigenen Datenzugriffsschicht zur Unterstützung dieser Klassen zu schreiben, oder Sie einige verfügbaren Dauerhaftigkeit dazu für Sie anbieten. Der Hauptvorteil der Code-zentrierten Option besteht, dass Entwickler die größter Flexibilität erhalten. Die Überlegung Kosten neigt dazu, auf den Ansatz für Dauerhaftigkeit ausgewählt fallen. Wenn ein Entwickler eine Projektmappe, die Ihr die Unternehmensdomäne anstelle der Infrastruktur Persistenz konzentrieren können auswählt, kann die allgemeine Leistung dieses Ansatzes sehr hoch sein.

Erstellen einer Forms zentrierte Anwendung
In diesem Abschnitt ich werde durchlaufen zum Erstellen einer sehr einfachen Anwendung Formulare-orientierten Ansatz mit der Entity Framework. Die erste Schritt ist die Erstellung einer Visual Studio Projekt. In diesem Beispiel wurde eine Anwendung dynamische Daten erstellt. In Visual Studio 2010, Sie wählen die Webanwendung Dynamic Data Entities, wie in Abbildung 2 dargestellt.
Abbildung 2 Visual Studio 2010 neu im Dialogfeld Projekt mit Dynamic Data Entities Web Application Projekt Vorlage ausgewählt.
Die nächste Schritt ist dessen Angabe der Entity Framework als Datenquelle für die Anwendung. Sie hierzu eine neue ADO.NET Entität Datenmodell Projektelement dem Projekt hinzufügen wie Sie sehen können, im Abbildung 3.
Abbildung 3 Add New Item Dialog Box mit ADO.NET Entity Data Model Project Element ausgewählt
Nach der Auswahl dieses Projektelement, führen Sie die folgenden drei Schritte aus:
  1. Wählen Sie zum Starten von einer Datenbank.
  2. Wählen Sie die Datenbank zum Ziel.
  3. Wählen Sie die Tabellen importieren.
Zu diesem Zeitpunkt Sie klicken Sie auf Fertig stellen und finden Sie in das Modell, das aus der Datenbank generiert wird, wie in Abbildung 4 dargestellt.
Abbildung 4 Standard Entity Data Model aus der Beispieldatenbank erstellte
Nun, dass das Modell generiert wurde, mit ausgeführt es in die dynamische Anwendung ist so einfach wie konfigurieren das Formular an den Objektkontext registrieren, der in den Schritten erstellt wurde weiter oben. In Global.asax.cs können Sie den folgenden Code im Kontext zeigen ändern:
DefaultModel.RegisterContext(typeof(NorthwindEntities), new   ContextConfiguration() 
    { ScaffoldAllTables = true});
Sie sollten jetzt können die Anwendung ausführen und eine funktionale Gruppe von Formularen über die persistenten Daten, sein, wie in Abbildung 5 dargestellt.
Abbildung 5 Standard Dynamic Data-Website mit
In dieser Übung wird die einfachste Formulare datengesteuerten Erfahrung veranschaulicht. Sie können jetzt beginnen, arbeiten wie die Präsentation aussehen soll und welche Verhaltensweisen Sie benötigen. ASP.NET Dynamic Data-Framework verwendet CLR-Attribute im Namespace System.ComponentModel.DataAnnotations zum Bereitstellen von Anleitungen auf wie die Daten dargestellt werden können. Beispielsweise können Sie ändern wie das Formular wiedergegeben wird, indem Sie eine Anmerkung, die eine Particluar-Spalte ausgeblendet. Das Attribut lautet wie folgt:
[ScaffoldColumn(false)]
Das Attribut "ScaffoldColumn" zeigt an, ob das Framework dynamische Daten die Spalte rendert. Das ScaffoldColumn-Attribut können Sie in einem Fall, in denen eine Tabelle ist dargestellt werden, entscheiden sich außerhalb des rendering einer bestimmten Spalte. Ist interessante Herausforderung in das aktuelle Szenario, wo und wann Sie eine Spalte-Attribut? In diesem Beispiel wurden die CLR-Klassen, die durch dynamische Daten verwendet werden generiert, aus der Entity Data Model . Sie können die generierten Klassen Attribut, aber dann werden alle Änderungen am Modell Verlust der Attribute verursachen. Dynamische Daten können auch Sie Attribute angewendet, mithilfe von partielle Klassen, die Ihre Klasse Entitäten zugeordnet, jedoch dann verlieren Sie einige Lesbarkeit und Erkennbarkeit aufgrund von Verlust der Kapselung.
Entity Framework 4.0 wird ein Erweiterungsmodell bereit, die ermöglicht Entwicklern die Tools Oberfläche des Entity Framework Designer erweitern und fügen zusätzliche Metadaten, die in Code oder Datenbank Generation; verwendet werden könnenDiese Funktionalität ist jedoch nicht verfügbar in Visual Studio 2010 Beta 1.
Die Entity Framework Entwickler dynamische Daten arbeiten möchte kann eine sehr produktive Erfahrung haben. Er kann mit einer Datenbank beginnen und Anmerkungen ein Modell mit den entsprechenden Metadaten Großteil dieses Erlebnis Laufwerk. Nachdem das Modell in guter Form ist, kann der Entwickler auf der Benutzeroberfläche konzentrieren. Weitere Informationen zum Verwenden von dynamischen Daten mit der Entity Framework, Bitte schauen Sie sich das offizielle Dynamic Data-Site.

Gedanken auf Forms zentrierte Anwendungen
Mit ASP.NET Dynamic Data und Entity Framework bietet eine äußerst produktive für die Entwicklung datenzentrischer Anwendungen. Formulare-zentrierte Anwendungen sind jedoch nicht lokal auf dynamische Daten. Viele Erfahrungen im Entwicklung für UI-erste Entwicklern ermöglichen, eine Anwendung erstellen, indem eine Reihe von Bildschirmen über eine Datenquelle erstellen in der Regel dieselben Merkmale aufweisen. Entwickler Erfahrung stützt sich im Allgemeinen auf eine Kombination aus Entwurfs- und Erfahrungen, die eine bestimmte Architektur Formatvorlage vorzugeben. Das Datenmodell entspricht häufig die Form der permanente Speicher (die zugrunde liegenden Tabellen), und es ist häufig fair etwas von UI-Metadaten (z. B. DataAnnotations im Fall von dynamische Daten), mit denen um die Benutzeroberfläche zu definieren.
Die Rolle der Entity Framework in eine Formulare zentrierten Erfahrung ist hauptsächlich als die Abstraktion über die zugrunde liegende Datenquelle. Ein Entwickler eine True setzen, um alle Modellmetadaten definieren, die Sie express müssen Erweiterbarkeit Funktionen bieten. Die Zuordnungsfunktionen ermöglichen ein Entwickler, die mid-tier Domäne Klassen umformen deklarativ ohne Infrastruktur Code eintauchen, nach unten.

Erstellen einer Modell-zentrierte Anwendung
Das Versprechen modellgesteuerte Entwicklung ist, dass Entwickler deklarativ ein Modell Ausdrücken können, der näher konzeptionelle Unternehmensdomäne als die Run-Time-Aspekte einer bestimmten Anwendung Architektur ist. Zum Zweck der in diesem Artikel habe ich konzentrierte sich auf der Erfahrung mit eine einzelnen Entwurfsoberfläche, auf dem Sie die Domäne und Verwandte Metadaten definieren und aus dem Sie die Klassen und Speicher bereitstellen.
In Microsoft .NET Framework, 4, gibt es eine Reihe von Innovationen in Entity Framework Werkzeuge, die eine Objektmodell-zentrierte Erfahrung aktivieren. Entity Framework Tools bietet eine grundlegende Erfahrung sowie die Funktionen für Framework-Entwickler, ISVs, und IT-Organisationen diese Funktionen zu erweitern. Um die Benutzerfreundlichkeit zu veranschaulichen, werde ich durch eine einfache Anwendung alle nötig sind.
Ich mit einem neuen Projekt dynamische Daten erneut starten und eine ADO.NET hinzufügen werde Entity Data Model Projektelement. Dieses Mal jedoch werde ich mit einem leeren Modell beginnen anstatt das Modell aus einer Datenbank erstellen. Beginnen Sie mit einer leeren Oberfläche, können Sie aus dem Modell erstellen soll. Ich werde eine sehr einfache Fitness-Anwendung mit nur zwei Entitätstypen Trainings und WorkoutType erstellen. Datenmodelle für die Typen sind in Abbildung 6 dargestellt.
Abbildung 6 Simple Entitätsdatenmodell
Wenn Sie ein Modell wie folgt im Entity Framework Designer definieren, ist keine Zuordnung oder speichern-Definition erstellt. Entity Framework-Designer können jedoch jetzt Entwickler ein Datenbankskript aus diesem Modell zu erstellen. Mit der rechten Maustaste auf die Designeroberfläche, können Sie generieren Skript von Datenbankmodell, wie im Abbildung 7 und den Entity Framework Designer eine Standarddatenbank aus das Entitätsmodell generiert. Für dieses Modell einfacher werden zwei Tabellen definiert. Die Namen der Tabellen übereinstimmen EntitySets, die im Designer definiert sind. In der Standard-Generation wird die Datenbank erstellt Verknüpfungstabellen für viele-zu-viele-Beziehungen erstellen und verwenden ein Schema Tabelle pro Typ (TPT) zum Erstellen von Tabellen, die eine Vererbungshierarchie unterstützen müssen.
Abbildung 7 Generieren eines Datenbank-Skripts aus dem Modell
Wenn Sie Datenbank-Skript aus Modell generieren aufrufen, eine neue T-SQL-Datei zum Projekt hinzugefügt und bietet dem Entitätsdatenmodell, die Sie erstellt haben die Entity Framework Metadaten mit gültigen Zuordnung und Informationsspeicher-Beschreibungen. Sie können diese in Abbildung 8 dargestellt.
Abbildung 8 der T-SQL-Datei aus dem Modell generiert
Wenn ein Entwickler Visual Studio Team Architect oder Team Suite verwendet wird, er bereitstellen und Ausführen der T-SQL-Skript innerhalb kann Visual Studio lediglich, indem Sie auf die Datei T-SQL, um es den Fokus erhält und dann F5 drücken. Sie werden aufgefordert, die Zieldatenbank auszuwählen, und anschließend das Skript ausgeführt.
Zum gleichen Zeitpunkt ausgeführt Entity Framework Designer die Standard-Codegenerierung, Klassen basierend auf dem Modell zu erstellen wird die Entity Framework Designer erforderlich, um beschreiben die Zuordnung zwischen dem Modell der Datenbank und eine Beschreibung des Datenspeichers, die erstellt wurde. Infolgedessen haben Sie jetzt eine stark typisierte Datenzugriffsschicht, die im Kontext der Anwendung verwendet werden können.
Zu diesem Zeitpunkt haben Sie gesehen, nur die Standardgruppe auftreten. Erweiterbarkeit des Entity Framework Designers können Sie viele Aspekte der Erfahrung modellgesteuerte anpassen. Die Datenbank-Generierung und Codegenerierung Schritte verwenden T4-Vorlagen, die zum Anpassen des Datenbankschemas und der Code, der erzeugt wird, angepasst werden können. Der Generierungsprozess der gesamten ist ein Windows Workflow Foundation (WF) Workflow, der auch angepasst werden kann und Sie haben bereits gesehen zum Hinzufügen von Erweiterungen zu den Tools Oberfläche mithilfe von verwalteten Erweiterbarkeit Framework-basierten Visual Studio Erweiterbarkeit. Ein Beispiel für diese Erweiterbarkeit sehen wir uns wie die code-generation-Schritt im Projekt geändert werden kann.
Mit der rechten Maustaste auf die Entwurfsoberfläche, können Sie neue Elemente generieren hinzufügen auswählen. Dieser Befehl öffnet das Dialogfeld in dem Sie keines der installierten Vorlagen zum Projekt hinzufügen auswählen können. Im Beispiel im Abbildung 9 ausgewählte Entity Framework POCO Codegenerator Vorlage (Hinweis: POCO Vorlage funktioniert nicht mit dynamischen Daten in Visual Studio 2010 Beta 1, aber es funktioniert in kommenden Versionen.) POCO (einfache alte CLR Objects) Klassen ermöglichen Entwicklern, nur die Elemente zu definieren, die Sie interessieren sich in deren Klassen und vermeiden diese Implementierung Details vom Framework Dauerhaftigkeit beschädigen. Mit .NET 4.0 haben wir eingeführt POCO Unterstützung innerhalb der Entity Framework, und eine Möglichkeit, POCO Klassen erstellen, wenn Sie eine Modell-zentrierten oder datenzentrischen Entwicklung Formatvorlage ist mit der POCO Vorlage. POCO Vorlage steht derzeit in ADO.NET Entity Framework Feature CTP 1, die von Data Platform Development heruntergeladen und mit Visual Studio 2010 Beta 1 verwendet werden kann.
Abbildung 9 Add New Item Dialog Box
Indem der EF ADO.NET POCO Codegenerator Vorlage erhalten Sie einen anderen Satz von generierten Klassen. Insbesondere können Sie eine Reihe von POCO Klassen als einzelne Datei pro Klasse, einer Hilfsklasse für Änderungen an verknüpften Elementen verwenden und eine eigene Kontextklasse generiert. Beachten Sie, dass Sie etwas in das Modell nicht. Sie haben lediglich die code-generation-Vorlage geändert.
Eine interessante Funktion, die in .NET 4.0 hinzugefügt ist die Fähigkeit definieren Sie Funktionen hinsichtlich der Entity Data Model . Diese Funktionen werden in das Modell ausgedrückt und können in Abfragen verwiesen werden. Überlegen Sie, eine Methode, um festzustellen, wie viele Kalorien in einer bestimmten Trainings gebrannt werden bereitstellen möchten. Es gibt keine Eigenschaft für den Typ, der die Kalorien gebrannt erfasst definiert. Sie konnte Abfragen die vorhandenen Typen und aufzählen dann die Ergebnisse berechnen die im Speicher; gebrannt Kalorienjedoch können mithilfe von Funktionen Modell definiert Sie Falten diese Abfrage in die Datenbankabfrage, die an den Informationsspeicher gesendet wird, daher ermöglicht eine effizientere Operation. Sie können die Funktion in der EDMX (XML) wie folgt definieren:
<Function Name="CaloriesBurned" ReturnType="Edm.Int32">
    <Parameter Name="workout" Type="Fitness.Workout" />
    <DefiningExpression>
        workout.Duration * workout.WorkoutType.CaloriesPerHour / 60
    </DefiningExpression>
</Function>
Damit diese Funktion in einem LINQ Abfrage, müssen Sie eine Funktion im Code bereitstellen, die genutzt werden können. Sie versehen diese Methode die Modell-Funktion anzugeben, die Sie verwenden möchten. Wenn die Funktion funktionsfähig wenn direkt aufgerufen werden soll, sollten Sie den Textkörper implementieren. Zum Zweck der in dieser Übung wir löst eine nicht unterstützte Ausnahme da wir zur Verwendung dieser Funktion in Form von erwarten LINQ Abfragen, die im Speicher abgelegt werden:
        [EdmFunction("Fitness", "CaloriesBurned")]
        public int CaloriesBurned(Workout workout) 
               { throw new NotSupportedException(); }
Wenn Sie eine Abfrage alle High-Kalorie Training abgerufen, bei denen eine hohe Kalorie Trainings größer als 1.000 Kalorien ist dann erstellen möchten, können Sie die folgende Abfrage schreiben:
    var highCalWorkouts = from w in context.MyWorkouts
                          where
                          context.CaloriesBurned(w) > 1000
                          select w;
Diese LINQ Abfrage ist eine gültige Abfrage, die die CaloriesBurned-Funktion kann jetzt nutzen und systemeigene T-SQL, die in der Datenbank ausgeführt werden, übersetzt werden.

Gedanken auf Modell-zentrierte Anwendungsentwicklung
Im degenerierte Fall, in denen ein Entwickler verwendet Modell erste Erfahrung und nicht die Schritte anpassen, ist den Modell-zentrierten sehr ähnlich wie das Formulare-zentrierten Erfahrung. Das Modell, dem der Entwickler arbeitet, ist ein Modell auf höherer Ebene als das logische Datenmodell, aber es ist immer noch eine ziemlich datenzentrischen Ansicht der Anwendung.
Entwickler, wer Ihre Entitätsdatenmodell ausgedrückt werden weitere Metadaten zu Ihrer Domäne erweitern und anpassen, die Generierung von Code und/oder der Datenbank, können an einer Stelle stammen, in dem die Erfahrungen eine Ansätze in dem Sie die Metadaten für die Laufzeit definieren. Dies eignet sich hervorragend für IT-Organisationen, die eine strenge Architektur und Codierungsstandards vorzugeben. Es ist auch sehr nützlich für ISVs oder Framework Entwickler, die zum Beschreiben des Modells den Entity Framework Designer als Ausgangspunkt verwenden und dann eine breitere End-to-End-Erfahrung daraus generieren möchten.

Code-zentrierte Anwendungsentwicklung
Die beste Möglichkeit, Code-zentrierten Anwendungsentwicklung beschreiben ist die Cliché Zitat "der Code ist die Wahrheit." Der Schwerpunkt liegt in der Formulare-orientierten Ansatz zum Erstellen einer Datenquelle und Benutzeroberflächenmodell für die Anwendung. Im Modell-orientierten Ansatz ist das Modell die Wahrheit: Definieren Sie ein Modell, und dann Generation erfolgt auf beiden Seiten (Speicher und die Anwendung). Im Code-orientierten Ansatz wird Ihre Absicht im Code erfasst.
Eine den Herausforderungen der Code-zentrierten Ansätzen ist der Kompromiss zwischen Domänenlogik und Infrastruktur-Logik. Object Relational Mapping (ORM) Lösungen in der Regel mit Code-zentrierten Ansätzen Hilfe, da Entwickler können Ihre Domänenmodell in Klassen Ausdrücken konzentrieren und lassen die ORM die Dauerhaftigkeit kümmern.
Wie wir im Modell-orientierten Ansatz gesehen haben, können POCO Klassen mit einer vorhandenen EDM-Modells (in entweder der erste Modell oder Datenbank erste Ansätze) verwendet werden. Im Code-orientierten Ansatz verwenden wir etwas Code nur, wir mit nur POCO Klassen und keine anderen Elemente beginnen aufgerufen. Code ist nur im ADO.NET Entity Framework Feature CTP 1, die von Data Platform Development heruntergeladen und mit Visual Studio 2010 Beta 1 verwendet werden können.
Berücksichtigen Sie die Fitness Anwendung nur Code replizieren. Idealerweise würden Sie die Domäne Klassen im Code wie in Abbildung 10 definieren.
    public class Workout
    {
        public int Id { get; set; }
        public DateTime DateTime { get; set; }
        public string Notes { get; set; }
        public int Duration { get; set; }
        public virtual WorkoutType WorkoutType { get; set; }

    }
    public class WorkoutType
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public int CaloriesPerHour { get; set; }
    }
Damit die Domäne Klassen mit Entity Framework arbeiten, müssen Sie eine spezielle ObjectContext definieren, die den Einstiegspunkt in das Entity Framework (ähnlich wie eine Sitzung oder Verbindung Abstraktion für die Interaktion mit der zugrunde liegenden Datenbank) darstellt. Die ObjectContext-Klasse muss die EntitySets definieren, die Sie über LINQ-Abfragen erstellen können. Hier ist ein Beispiel des Codes:
    public class FitnessContext : ObjectContext
    {
        public FitnessContext(EntityConnection connection)
            : base(connection, "FitnessContext")
        {
        }

        public IObjectSet<Workout> Workouts { 
            get { return this.CreateObjectSet<Workout>(); } }

        public IObjectSet<WorkoutType> WorkoutTypes { 
            get { return this.CreateObjectSet<WorkoutType>(); } }
    }
Die Erfahrung Code schreibgeschützt wird eine Factoryklasse verwendet, um eine Instanz des Kontexts abzurufen. Diese Kontextklasse über den Kontext wiedergibt und die erforderlichen Metadaten für die Ausführung zur Laufzeit erstellt. Die Factory Signatur lautet wie folgt:
ContextBuilder.Create<T>(SqlConnection conn)
Zur Vereinfachung können Sie eine Factorymethode dem erzeugten Kontext hinzufügen. Sie bieten ein statisches Feld für die Verbindungszeichenfolge und eine statische Factorymethode, Instanzen von einem FitnessContext zurückzugeben. Erste die Verbindungszeichenfolge:
        static readonly string connString = new SqlConnectionStringBuilder
        {
            IntegratedSecurity = true,
            DataSource = ".\\sqlexpress",
            InitialCatalog = "FitnessExpress",
        }.ConnectionString;
Und hier ist die Factorymethode:
        public static FitnessContext CreateContext()
        {
            return ContextBuilder.Create<FitnessContext>(
                                   new SqlConnection(connString));
        }
Mit diesem haben Sie genug, um damit den Kontext verwendet werden. Sie können z. B. eine Methode wie die folgenden Abfragen alle Trainings-Typen schreiben:
        public List<WorkoutType> AllWorkoutTypes()
        {
            FitnessContext context = FitnessContext.CreateContext();
            return (from w in context.WorkoutTypes select w).ToList();            
        }
Wie bei Model-First-Erfahrung, ist es nützlich, um eine Datenbank aus der Code nur Erfahrung bereitstellen können. Die ContextBuilder stellt einige Hilfsmethoden, die überprüfen können, ob eine Datenbank vorhanden ist, legen Sie, wenn Sie möchten, und Sie erstellen.
Sie können Code wie den folgenden Demo-Funktionalität mithilfe des Ansatzes Code nur eine Reihe einfache bootstrap schreiben:
        public void CreateDatabase()
        {
            using (FitnessContext context = FitnessContext.CreateContext())
            {
                if (context.DatabaseExists())
                {
                    context.DropDatabase();
                }
                context.CreateDatabase();
            }
        }
Zu diesem Zeitpunkt können Sie die Repository-Musters von Domäne-driven Design (TTT), um etwas in was wir bisher gesehen haben präziser zu formulieren. Die Verwendung von TTT Prinzipien ist eine allgemeine Trend heute Anwendungsentwicklung, jedoch wird nicht versucht wird, definieren oder Verbreitung Domäne Entwurf hier gesteuert. (Weitere Informationen, finden Sie in der Inhalte von Experten wie Eric Evans ( Domain-Driven Design: Übernehmen die Komplexität in das Herz von Software , Addison-Wesley, 2003) und Jimmy Nilsson ( anwenden Domain-Driven Design und Muster: Mit Beispiele in C#- und , Addison-Wesley, 2006).
Derzeit haben wir eine handschriftliche Domäne Klassen und eine spezielle ObjectContext. Wenn wir dynamische Daten verwendet, zeigt wir einfach das Framework der ObjectContext. Aber wenn wir eine stärkere Abstraktion der unser zugrunde liegenden Dauerhaftigkeit Layer berücksichtigen möchten und wir wirklich den Vertrag Operationen nur die sinnvolle Domänenoperationen einschränken, die eine tun möchten, können wir die Repository-Musters nutzen.
Für dieses Beispiel werde ich zwei Repositorys definieren: eine für WorkoutTypes und eine für Trainings. Wenn Sie TTT Prinzipien befolgen, sollten Sie Ihrer Meinung nach über Aggregatfunktionen Root(s) Festplatte und Modellierung des Repositorys entsprechend überlegen. In diesem einfachen Beispiel habe ich habe zwei Repositorys verwendet, um allgemeine Konzepte. Abbildung 11 zeigt das WorkoutType-Repository, und Abbildung 12 zeigt das Trainings-Repository.
    public class WorkoutTypeRepository
    {
         public WorkoutTypeRepository()
         {
              _context = FitnessContext.CreateContext();
         }
         public List<WorkoutType> AllWorkoutTypes()
         {
              return _context.WorkoutTypes.ToList();
         }
         public WorkoutType WorkoutTypeForName(string name)
         {
              return (from w in _context.WorkoutTypes
              where w.Name == name
              select w).FirstOrDefault();
         }
         public void AddWorkoutType(WorkoutType workoutType)
         {
              _context.WorkoutTypes.AddObject(workoutType);
         }
         public void Save()
         {
              this._context.SaveChanges();
         }
         private FitnessContext _context;
    }
    public class WorkoutRepository
    {
        public WorkoutRepository()
        {
            _context = FitnessContext.CreateContext();
        }

        public Workout WorkoutForId(int Id)
        {
            return (from w in _context.Workouts where w.Id == Id select w).FirstOrDefault();
        }

        public List<Workout> WorkoutsForDate(DateTime date)
        {
            return (from w in _context.Workouts where w.DateTime == date select w).ToList();
        }

        public Workout CreateWorkout(int id, DateTime dateTime, int 
                  duration, string notes, WorkoutType workoutType)
        {
            _context.WorkoutTypes.Attach(workoutType);
            Workout workout = new Workout() { Id = id, DateTime = dateTime, Duration = duration,
              Notes = notes, WorkoutType = workoutType };
            _context.Workouts.AddObject(workout);
            return workout;
        }

        public void Save()
        {
            _context.SaveChanges();
        }

        private FitnessContext _context;

    }
Eine interessante Sache zu beachten ist, dass die Rückgabetypen nicht IQueryable < T >; sindSie sind List < T >. Es gibt Diskussionen über, ob Sie über die Begrenzungen der Dauerhaftigkeit Schicht IQueryable bereitstellen sollten. Meiner Meinung nach ist, dass Verfügbarmachen IQueryable der Kapselung der Dauerhaftigkeit Layer und Kompromissen unterbricht die Grenze zwischen explizite Vorgänge, die im Speicher stattfinden und Operationen, die in der Datenbank auftreten. Wenn Sie eine IQueryable < T > verfügbar machenaus dem Repository, die Sie haben keine Ahnung, beendet wird, einrichten eine Datenbankabfrage in Verfassen LINQ weiter oben im Stapel.
Diese Repositorys können nun einige Daten im Speicher hinzufügen. Abbildung 13 zeigt zwei Methoden, die zum Erstellen der Beispieldaten verwendet werden könnten.
public void AddWorkouts()
{
     Console.WriteLine("--- adding workouts ---");
     WorkoutRepository repository = new WorkoutRepository();
     WorkoutTypeRepository typeRepository = new WorkoutTypeRepository();

     WorkoutType squash = typeRepository.WorkoutTypeForName("Squash");
     WorkoutType running = typeRepository.WorkoutTypeForName("Running");

     repository.CreateWorkout(0,new DateTime(2009, 4, 20, 7, 0, 0),
       60, "nice squash workout", squash);
     repository.CreateWorkout(1, new DateTime(2009, 4, 21, 7, 0, 0),
       180, "long run", running);
     repository.CreateWorkout(2, new DateTime(2009, 4, 22, 7, 0, 0),
       45, "short squash match", squash);
     repository.CreateWorkout(3, new DateTime(2009, 4, 23, 7, 0, 0),
       120, "really long squash", squash);
     repository.Save();
}
Im Modell-First-Szenario verwendet wir Modell benutzerdefinierte Funktionen, um eine Methode zum Bestimmen wie viele Kalorien in einer bestimmten Trainings gebrannt werden, obwohl es ist keine Eigenschaft für den Typ, der die Kalorien gebrannt erfasst definiert bereitzustellen. Mit dem Code nur Ansatz müssen Sie die Option zum Definieren Sie Funktionen Modell definiert hier keinen. Sie können jedoch Verfassen von vorhandenen Trainings-EntitySet, eine Abfrage, die bereits den Filter hoch Kalorie kapselt zu definieren, wie hier gezeigt:
        public IQueryable<Workout> HighCalorieWorkouts()
        {
            return (
              from w in Workouts 
               where (w.Duration * w.WorkoutType.CaloriesPerHour / 60) > 1000
                 select w);
        }
Wenn wir diese Methode auf die FitnessContext definieren, können wir dann es im Trainings-Repository folgendermaßen nutzen:
        public List<Workout> HighCalorieWorkouts()
        {
            return _context.HighCalorieWorkouts().ToList();
        }
Da die Methode auf dem Kontext ein IQueryable zurückgegeben, Sie weiter darauf verfasst haben könnte, aber ich habe, für die Symmetrie, zu nur entschieden rückgegeben Sie die Ergebnisse als Liste .

Gedanken über Code zentrierte Entwicklung
Die Code-zentrierte Erfahrung ist sehr interessant für Entwickler ihre Domänenlogik im Code möchten. Die Code-zentrierte Erfahrung eignet sich gut für bietet ein Maß an Flexibilität und Klarheit zum Arbeiten mit anderen Frameworks. Abstraktionen wie das Repository-Musters verwenden, kann diese Vorgehensweise Entwickler ein hohes Maß an Isolierung für den Layer Dauerhaftigkeit bereitstellen, die die Anwendung der Dauerhaftigkeit Schicht bekannt bleiben ermöglicht.

Letzte Thoughts auf Application Development Formatvorlagen
Diese sind die drei Anwendung Entwicklung Formate, die wir oft angezeigt werden. Wie bereits erwähnt, besteht keine einzelne, true Klassifizierung von diese Entwicklung Formatvorlagen. Sie liegen mehr auf ein Kontinuum von sehr ausführlichen sehr datenzentrischen und CRUD-zentrierten auftritt, Schwerpunkt Produktivität zu sehr Ausdrucksstark Code zentrierten Erfahrungen.
Für alle von diesen die Entity Framework an die Dauerhaftigkeit Schicht genutzt werden können. Wenn Sie in der Formular-zentrierten und Modell-zentrierte Seite des des Spektrums Richtung bewegen, explizite Modell und die Möglichkeit zum Erweitern der Kette Modell und Tool helfen die Entity Framework insgesamt Entwicklerproduktivität verbessern. Auf der Code-zentrierte Seite die Verbesserungen in den Entity Framework ermöglichen die Runtime aus dem Weg zu erhalten und werden lediglich ein Implementierungsdetail für Dauerhaftigkeit Dienste.

Tim Mallalieu ist der Einheit Produktmanager für Entity Framework und LINQ to SQL. Er kann unter blogs.msdn.com/adonet erreicht.

Page view tracker