Code-First Development with Entity Framework (2015)
Appendix A. Answers to Self-test Questions
Chapter 1: Introducing Entity Framework
Q1. Impedance mismatch between RDBMS and object-orientated programming is the main problem that ORM tools solve. They enable developers to talk to databases in the same way they talk to any other object, using the same programming language, such as C# or VB.NET.
Q2. This statement is false. LINQ can be used to create queries in Entity Framework, thus enabling developers to use C# or VB.NET instead of the SQL language.
Q3. Entity Framework Migrations are used to script and apply structural changes to the database, thus moving it from one version of your software to the next.
Q4. DbContext is the abstraction that represents a database you are working with using Entity Framework Code-First. It has collection-based properties that represent tables in the database.
Q5. The answer is false. As Entity Framework uses the provider architecture; it can work with any database that has a provider written for it. At this point, all major database engines are supported, such as MySQL, DB2, and Oracle.
Chapter 2: Your First Entity Framework Application
Q1. DbSet<T> is the class you should be using to define a property in your context class that corresponds to a table in your database. The type parameter T represents a class that defines that table's structure in terms of .NET.
Q2. As DbContext holds an underlying connection to the database, you should utilize the IDisposable pattern and call Dispose on your context when you are done using it. You can also use the Using keyword to achieve the same.
Q3. The Find method can be used to locate a row in the database. It takes one or more parameters corresponding to the values of the primary key. If you have a single column that defines the primary key, only one value is needed. Multiple parameter values are reserved for tables with complex multicolumn primary keys.
Q4. You can use the Remove method and pass in an instance you would like to be deleted from the database when SaveChanges is called on your context.
Q5. You can just find the corresponding object and set its LastName property to new values. Then, you can call SaveChanges to commit the updated data to the database. You can use the Find method or LINQ to locate the matching row in the database. We will see other methods to issue updates in later chapters.
Q6. You will get an exception because no initializer is used. We will see in later chapters how migrations solve this problem.
Chapter 3: Defining the Database Structure
Q1. If you want to make a value optional, you need to use nullable types in Entity Framework. As we need to store an integer value, the correct answer is Int.
Q2. The statement is false because the string is a nullable type in .NET. Hence, by default the column will be nullable as well.
Q3. The statement is false. You can remove the conventions from the Entity Framework configuration using the Remove method on the Conventions collection in the model builder.
Q4. Many-to-Default is not a relationship type. One-to-Many (or One-to-Zero-to-Many), One-to-One (or One-to-Zero-to-One), and Many-to-Many are the correct relationship types.
Q5. The answer is false. This approach will become unwieldy if you have many tables in the database.
Q6. By default, Entity Framework will use Unicode types, such as nvarchar for string properties. As there are no constraints on the string property, the correct type will be nvarchar(max).
Q7. Domain is not a relationship type.
Q8. EntityTypeConfiguration is the correct "buddy" class to be used to configure persistence for an entity.
Chapter 4: Querying, Inserting, Updating, and Deleting Data
Q1. LINQ supports two types of query syntaxes—method, which looks like any other method calls in your programming language, and Query, which resembles SQL in its appearance.
Q2. The answer is false. If an entity is tracked by the context after retrieval, all changes are tracked individually. Hence, Entity Framework will create an update query that only includes columns/properties touched by the code after the entity in question was retrieved.
Q3. Only the first property in the sort order is specified by the OrderBy method; all subsequent ones should be specified by the ThenBy method calls.
Q4. In order to specify multiple conditions, you need to use logical operators in a single Where method.
Q5. All of the approaches are valid, although you may find that the AddRange is a bit more readable.
Q6. The answer is false. Insert operations are different from other operations. You can add a root entity to its DbSet, and all child entities are assumed to be in new state as well.
Q7. True, since context was not tracking entities prior to the state being set, context has to assume that all properties have been changed.
Q8. The answer is false. If you want to issue a delete query, you need to attach an entity instead of adding it in order to simulate an existing entity in the unchanged state.
Q9. The detached state corresponds to any entity not tracked by the context. Since it is not tracked, DbContext will not look at this entity when SaveChanges is called. Entities in the unchanged state will also not result in any queries, but they are tracked by the context.
Q10. The local property of DbSet will give you access to in-memory data only and will never result in a database query to look for data.
Chapter 5: Advanced Modeling and Querying Techniques
Q1. Since we are not creating a new entity, but a complex type, we need to use ComplexTypeConfiguration of the T base class to configure it.
Q2. The answer is false. We can use the ToTable method in order to configure an entity to be stored in a table with a name that is different from the class name for this entity.
Q3. The answer is false. We can use the Ignore method to exclude some properties from the persistence engine.
Q4. The process of selecting a subset of columns from a table, that is, a subset of properties from an entity, is called projection.
Q5. We do not have to declare a type for a result set; we can always use anonymous types.
Q6. We do not have to use joins to get related data in a query, since relationships exist in properties inside entities. Thus, related data is available inside a query by walking through these association properties.
Q7. In order to repeat parent entity data along with child data in the result set, we need to use SelectMany method of LINQ.
Q8. The set operator Distinct can be used to create a set of unique values from a query.
Q9. We cannot accomplish LEFT OUTER JOIN in LINQ with a single method.
Q10. The Skip and Take methods are used to accomplish paging. The Skip method, as the name implies, excludes some number of records from the result set, even though they match the filter. The Take method only takes a specified number of rows to include in the result set, even though more rows match the filter.
Q11. We can definitely create grouping queries based on multiple properties. We can typically use the anonymous type to specify which properties the grouped data is based on.
Chapter 6: Working with Views, Stored Procedures, the Asynchronous API, and Concurrency
Q1. Although there is no first class support for views in Entity Framework, we can always retrieve data from a view using the SqlQuery method.
Q2. The SqlQuery method can be used to call an arbitrary SQL statement, including calling stored procedures or functions. Entity Framework will materialize the results based on the generic type provided to this method.
Q3. This is not correct. Insert, update, and delete operations can be automatically generated by Entity Framework. All we need to do is map an entity to stored procedures inside an entity type configuration class.
Q4. This is not correct. Arbitrary use of the asynchronous API can result in performance overhead.
Q5. SaveChangesAsync is the method on DbContext that can be called to flush changes to the database asynchronously.
Q6. IsRowVersion is the only method called that needs to be made on the property configuration class to mark a property as concurrency check property.
Q7. DbUpdateConcurrencyException is the correct type to catch from Entity Framework Code-First to handle concurrency errors.
Chapter 7: Database Migrations and Additional Features
Q1. This is correct. You have to run the Enable-Migrations commandlet to easily create all the necessary artifacts to support migrations.
Q2. The answer is false. Some operations, such as setting custom default values, cannot be done with automatic migrations. Neither can we create non-Entity Framework objects, such as stored procedures.
Q3. The answer is false. Entity Framework needs to compare our model, defined by entity classes and context, with the target database to know what structures have changed.
Q4. The answer is C—we need to create an empty migration which signals to Entity Framework that the target structure matches the model.
Q5. This is not correct. We can use the NuGet Package Manager Console window to run commandlets to maintain a local database.
Q6. The answer is false. The DbMigration class exposes many methods, including those that create stored procedures.
Q7. The answer is false. We can use conventions or global configuration methods of DbModelBuilder to achieve this task.
Q8. The answer is false. We can use the Log property of the Database object to log commands run by Entity Framework against the database.
Q9. This is not correct. We can create LINQ queries and use methods of the DbGeometry and DbGeography classes to execute native geospatial queries against the database.