The errata list is a list of errors and their corrections that were found after the product was released.
The following errata were submitted by our customers and have not yet been approved or disproved by the author or editor. They solely represent the opinion of the customer.
Version |
Location |
Description |
Submitted by |
Date submitted |
Printed |
Page x
x |
NOTE TO ERRATA SUBMITTERS (May 14):
I wanted to be sure you knew that am not ignoring the new submissions. I have been waiting to get a copy of the 2nd Printing of the book (which contains corrections) so that I can verify which of the newly submitted errata has already been fixed before I process it.
Julie
|
 Julia Lerman |
May 16, 2009 |
Printed |
Page pgs 373-378
UnpaidReservations walkthrough |
Julie,
After spending some time getting the UnpaidReservations Defining Query to work as defined on pages 373-378 I almost gave up. I searched and found the updated edmx file that is included in the seperate download for chapter 14. After comparing and modifiying my edmx through the xml editor was I able to get the example to work.
The Chapter 14 copy of the BAModel.edmx had a couple of attributes that make the UnpaidReservations work.
The association mapping in the C-S for example should be
<AssociationSetMapping Name="ReservationUnpaidReservation" TypeName="BAModel.ReservationUnpaidReservation" StoreEntitySet="UnpaidReservations">
<EndProperty Name="UnpaidReservation">
<ScalarProperty Name="ID" ColumnName="ID" /></EndProperty>
<EndProperty Name="Reservation">
<ScalarProperty Name="ReservationID" ColumnName="ReservationID" />
</EndProperty>
<Condition ColumnName="ReservationID" IsNull="false"/>
</AssociationSetMapping>
The condition is critical
Another item is the Entity Type for the UnpaidReservation in the SSDL should be
<EntityType Name="UnpaidReservation" >
<Key>
<PropertyRef Name="ID" />
</Key>
<Property Name="ID" Type="int" Nullable="false" />
<Property Name="ReservationID" Type="int" Nullable="true" />
<Property Name="PaymentTotal" Type="money" Nullable="false" />
<Property Name="Cost" Type="money" Nullable="false" />
</EntityType>
There is also a subtle change in the DefiningQuery
<EntitySet Name="UnpaidReservations" EntityType="BreakAwayModel.Store.UnpaidReservation">
<DefiningQuery>
SELECT r.reservationid AS ID, SUM(amount) AS PaymentTotal,
MIN(events.[TripCostUSD]) AS cost,r.reservationID
FROM reservations r
JOIN payments p ON r.[ReservationID]=p.[ReservationID]
JOIN events ON r.[EventID]=events.[EventID]
GROUP BY r.[ReservationID]
HAVING SUM(amount)<min(TripCostUSD)
UNION
SELECT r.reservationid, 0,MIN(events.[TripCostUSD]) AS cost,r.ReservationID
FROM reservations r
JOIN events ON r.[EventID]=events.[EventID]
WHERE r.[ReservationID] NOT IN (SELECT reservationID FROM payments)
GROUP BY r.[ReservationID]
</DefiningQuery>
</EntitySet>
I am not sure if I have listed all of the changes nessesary or in the correct order to correct the issues. Would it be possible to perhaps update the process in the errata so others can work the example.
I am enjoying the book and am impressed with the breadth of the subject matter. It must have been a bit like eating a whale to produce a book such as this one. I look forward to purchasing the next version with hopefully the EF V4 changes.
~Ian
|
Ian B |
Aug 06, 2009 |
|
2
Above Figure 1.3 in the Sample Code (Both VB and C#) |
Was reading the online version so the page number is probably incorrect as there is no page numbering in the online version.
I'm a little confused on where the "People" object is coming from in the sample Code:
From p In People.OfType(Of SalesPerson) Select p
In your Figure 1.2, the object is named "Person"
Should the sample code read:
From p In Person.OfType(Of SalesPerson) Select p
Am I miss understanding something?
Thank You.
|
Ming Hsueh |
Aug 26, 2009 |
Printed |
Page 80
bottom |
On the bottom of page 80, you mention that the datatype for the contacts variable will show that it is a IQueryable of an "anonymous type". The type of the variable is actuall a System.Data.Objects.ObjectQuery of an "anonymous type". Of course, the ObjectQuery class implements IQueryable, but the correct type to show is System.Data.Objects.ObjectQuery
I love the book! Keep up the great work!
Bennie
|
Bennie Haelen |
Aug 26, 2009 |
PDF |
Page 80
4th paragraph |
It says: "Anonymous types are generally used for on-the-fly types that won’t be used elsewhere
in the application. You cannot even pass them from one method to another."
Maybe at the time you write this book, you couldn't pass an anonymous type from one method to another. But now you can if the receiving method receives a dynamic.
|
Gustavo Díaz |
Mar 02, 2014 |
Printed |
Page 85
example4-5 VBsection |
change
PEF.CreateQuery(Of DbDataRecord)(strQ)
to
Dim Contacts = context.CreateQuery(Of DbDataRecord)(strQ)
|
Ceulemans P |
Dec 26, 2009 |
Printed |
Page 147
All Code samples |
All references to ("WA") should be ("Washington").
|
Greg Lee |
Aug 03, 2009 |
Printed |
Page 148
Last Paragraph |
The author states that if you delete an Entity from a model and later wish to recreate it you can: 2)Delete the Entity from the model and then edit the XML and delete its EntitySet and EntityType. I found that you also have to delete any navigation associations with any other entity otherwise the Designer won't be able to display the model any more.
|
Ruddy Santos |
Aug 17, 2009 |
Printed |
Page 176
Example 8.1. Querying for customers in the form load |
The first line of code (i.e. var context = new BAGA.BAEntities();) will fail initializing a new BAObjects object using the connection string from the app.config file (I copied mine from the model project as suggested in the text) if you made the change discussed on page 167 concerning spliting out the schema files. This (as discussed on page 168) changes the app.config file's connection string to reflect the new location of the schema files, which is relative the model project, not the windows forms project.
I had to change my "Copy To Output Directory" property on the app.config file of the model project back to "Do not copy" and recompile so the schema files are embedded - then copy/paste the updated app.config file into the windows forms project.
Now the queries run as expected. I realize this may be just related to how I did it and followed along but I did not see anything mentionded about this so I thought I would submit it.
Thanks, Julia. I am enjoying the book and am looking forward to V2 of EF ... and your updated book, of course. :-)
|
Ron Landers |
Jul 31, 2009 |
Printed |
Page 177
top line |
The C# line should be changed from
.Execute(Objects.MergeOption.AppendOnly);
to
.Execute(MergeOption.AppendOnly);
I don't know if this affects the VB code.
|
Mike Bridge |
Jul 10, 2009 |
Printed |
Page 186
Example 8-4 code - VB & C# |
need to add the code to bind the customers data to the form:
customerBindingSource.DataSource = customers; // C# version
|
Greg Lee |
Aug 04, 2009 |
Printed |
Page 188
Second paragraph |
The paragraph in question reads "To do this, you will need to create one new Object data source for the BAGA.Activity class and one for the BAGA.Destination class." This pretty much stopped me cold. I created the two object data sources, but couldn't get the drop downs shown in Figure 8-11 to display the choices. I finally went back to the project data sources window and added BAGA.Activity and BAGA.Destination and then set them to DataSource in the appropriate object data source. Then I was able to get the drop downs to work and set the appropriate properties. I'm not at all sure that this is what you intended as it seems my setting up those DataSources gets changed in the code below that paragraph. I'm a web programmer, not a windows forms programmer, so maybe this would be obvious to someone with that background, but it wasn't to me. Perhaps an expansion/clarification is in order?
|
BillHyde |
Jul 03, 2009 |
Printed |
Page 188
Testing the sample again |
I had a problem with the secondary activity and secondary destination not being correct for the first record only - they were displaying the first entry in the combobox display lists instead of the correct values; all other records worked correctly.
I finally determined that is was due to setting the customerBindingSource.DataSource before setting the activityBindingSource.DataSource and the destinationBindingSource.DataSource.
Why is this the case? It seems like a nasty source of bugs and perhaps a warning would be worthwhile...
|
Greg Lee |
Aug 04, 2009 |
Printed |
Page 203
1st paragraph |
you need to change the Customer query in the WIndow.Loaded event.
A think it should be :
you need to change the Trip query in the WIndow.Loaded event.
|
Ryohsuke Fujioka |
Oct 10, 2009 |
Printed |
Page 205
1st paragraph |
Run the form and edit one of the trips, changing a date and the loadging.
But before close the form, I think we have to click the save button.
|
Ryohsuke Fujioka |
Oct 10, 2009 |
Printed |
Page 206
1st paragraph |
The statement that ComboBox does not support updating is untrue: both SelectedValue and SelectedItem properties are two-way properties. In order to be useful for updating the related Location entity, one would rather bind to SelectedItem like this:
<ComboBox Name="comboBoxLodgingPartner" ... DisplayMemberPath="LodgingName" SelectedItem="{Binding ElementName=listBoxTrips, Path=SelectedItem.Lodging}" />
The assignment to SelectedValuePath can be dropped as well.
|
Matthias Schwalbe |
Aug 12, 2009 |
Printed |
Page 246
2nd paragraph |
and will automatically deserialize it to a Customer object:
should be :
and will automatically deserialize it to a Contact object:
and VB code sammple should be :
Private Sub GetContactFromService()
Dim proxy =
New BreakAwayCommonService.BreakAwayCommonServiceClient
Dim contact = proxy.GetContact(21)
Console.WriteLine("{0} {1}", contact.FirstName.Trim,
contact.LastName.Trim)
End Sub
|
Ryohsuke Fujioka |
Oct 10, 2009 |
Printed |
Page 250
Example 10-1 |
VB
Partial Public Class BreakAwayEntities
should be :
Partial Public Class BAEntities
C#
public partial class BreakAwayEntities :
should be :
public partial class BAEntities :
|
Ryohsuke Fujioka |
Oct 10, 2009 |
Printed |
Page 253
1st note |
ObjectContext also has a pair of Changed and Changing events.
should be :
EntityObject also has a pair of [Paoperty]Changed and
[Paoperty]Changing events.
|
Ryohsuke Fujioka |
Oct 10, 2009 |
Printed |
Page 254
3rd paragraph |
In VB, select Address from the Class Name drop-down;
should be :
In VB, select Activity from the Class Name drop-down;
and
Choose OnAddressIDChanging and OnAddressIDChanged,
should be :
Choose OnActivityNameChanging and OnActivityNameChanged,
|
Ryohsuke Fujioka |
Oct 10, 2009 |
Printed |
Page 255
1st paragraph |
This means you can impact whatever you wish about the Address entity in this business logic.
should be :
This means you can impact whatever you wish about the Activity entity in this business logic.
|
Ryohsuke Fujioka |
Oct 10, 2009 |
Printed |
Page 259
Column |
It is true that we can't use enum value directly when building a Entitykey.
So the next code
new EntityKey("BAEntities.CustomerTypes", "CustomerTypeID",
CustType.Standard);
throw an ArgumentException that inform us that the third parameter is not Int32.
You said that unfortunately we had to write this code like next.
new EntityKey("BAEntities.CustomerTypes", "CustomerTypeID", 1);
But it's a pity we have to use such a magic numeber.
I think it's much better if we write this code like next.
new EntityKey("BAEntities.CustomerTypes", "CustomerTypeID",
(int)CustType.Standard);
|
Ryohsuke Fujioka |
Oct 18, 2009 |
Printed |
Page 263
Example 10-10 |
Dim custOnOtherEnd = CType(e.Element, Customer)
should be :
Dim contactOnOtherEnd = CType(e.Element, Contact)
and next page(264)
Partial Public Class Customer
should be :
Partial Public Class Contact
|
Ryohsuke Fujioka |
Oct 10, 2009 |
Printed |
Page 264
C# Code example |
public Address()
{
this.CustomerReference.AssociationChanged +=
new CollectionChangedEventArgs(Add_CustRefChanged);
}
should be :
public Address()
{
this.CustomerReference.AssociationChanged +=
new CollectionChangedEventHandler(Add_ContactRefChanged);
}
and
private void Add_CustRefChanged(object sender,
CollectionChangeEventArgs e)
{
CollectionChangeAction act = e.Action;
Customer custOnOtherEnd = (Customer)e.Element;
//add your logic here
}
should be :
private void Add_ContactRefChanged(object sender,
CollectionChangeEventArgs e)
{
CollectionChangeAction act = e.Action;
Contact contactOnOtherEnd = (Contact)e.Element;
//add your logic here
}
and
public partial class Customer
{
public Customer()
{
should be :
public partial class Contact
{
public Contact()
{
|
Ryohsuke Fujioka |
Oct 10, 2009 |
Printed |
Page 264
2nd paragraph |
An errata is already submitted for pg. 164. A second fix would be:
// Implementing AssiciationChanged
this.Contact.CustomerReference.AssociationChanged +=
new CollectionChangeEventHandler(CustomerReference_AssociationChanged);
and:
void CustomerReference_AssociationChanged(object sender, CollectionChangeEventArgs e)
{
CollectionChangeAction action = e.Action;
Customer customer = e.Element as Customer;
// Add logic here;
}
|
Bob Bedell |
Oct 25, 2009 |
Printed |
Page 277
Ist paragraph |
Now you get to see the ObjectDataSource in action.
should be :
Now you get to see the EntityDataSource in action.
|
Ryohsuke Fujioka |
Oct 10, 2009 |
Printed |
Page 288
Example 11-2, 5th line |
In Example 11-2, line 5 "AutoGenerateWhere=True" should be "AutoGenerateWhereClause=True"
|
BillHyde |
Aug 20, 2009 |
Printed |
Page 288
Example 11-2, 4th line |
In Example 11-2, line 4 reads
'EntitySetName="Contacts" EntityTypeFilter="Customer"'
Setting EntityTypeFilter to Customer generates an error be cause it is not a type or derived type of EntitySet Contacts. Setting EntityTypeFilter to "Contact" or omitting it entirely removes the error condition.
|
BillHyde |
Aug 20, 2009 |
Printed |
Page 293
Item 3 under "Creating a Parent EntityDatasource ..." |
On page 293 under the topic "Creating a Parent EntityDataSource ..." item 3 in the list states "Set the EntityDataSource's ConnectionString and EntityContainer to BAEntities." The word "ConnectionString" should be "Named Connection".
|
BillHyde |
Aug 21, 2009 |
Printed |
Page 294
select clause after 2nd paragraph and also in 3rd paragraph |
On page 294 is a select between paragraphs 2 and 3 that has a where clause -- Where="count(select value r.ReservationID from c.Reservations as r) > 0". The predicate of this clause "count..." when inserted in the "where" property of the EntityDataSource that is bound to the drop down list produces an error "'c.Reservations' could not be resolved in the current scope or context. Make sure that all referenced variables are in scope, that required schemas are loaded, and that namespaces are referenced correctly., near multipart identifier, line 9, column 41."
This seems to resolve if one drops the "c." in front of Reservations making the where property "count(select value r.ReservationID from Reservations as r)".
I have no clue why this works and the first one doesn't. When I look up the where property in MSDN it seems to preface most names by "it.". I tried that in this case and it doesn't work either. As someone said I am working with dark forces beyond by knowledge (or something like that).
|
BillHyde |
Aug 21, 2009 |
Printed |
Page 296
List item 3 under heading "Using a New EntityDataSource ..." |
In list item 3 under the heading "Using a New EntityDataSource ..." change "From the GridView Tasks window" to "From the ListView Tasks window".
|
BillHyde |
Aug 22, 2009 |
Printed |
Page 299
|
I'm Sorry for my bad English because I am Japanese and usually not use English.
I bumped into the same problem that Joseph did.
The problem is that when I selected new item on dropdownList,
items of listBox changed but context of paymentsDS didn't be
recreated.(Creating event didn't be called.)
I found a workaround for this problem although it's not cool, but work at least.
First, I don't use AutoGenerateWhereClause and set Where parameter to
"it.Reservation.ReservationID=@Hoge" and set WhereParameters to asp:Parameter named Hoge, not asp:ControlParameter.
(All of these setting can be done from property window.)
<asp:EntityDataSource ID="PaymentDS" runat="server"
ConnectionString="name=BAEntities"
DefaultContainerName="BAEntities"
EnableInsert="True" EntitySetName="Payments"
=> Where="it.Reservation.ReservationID=@Hoge"
oninserting="PaymentDS_Inserting">
<WhereParameters>
=> <asp:Parameter DbType="Int32" DefaultValue="0"
Name="Hoge" />
</WhereParameters>
</asp:EntityDataSource>
2nd, to assign this parameter correct value, I manually wrote codes in 2 places.
One is at ContactDS's Selected event.
Two is at ListBox's SelectedIndexChanged event.
That's all. Only two sentences.
protected void ContactDS_Selected(object sender,
EntityDataSourceSelectedEventArgs e)
{
var contact = e.Results.Cast<Contact>();
var res = contact.First().Customer.Reservations;
if (res.Count > 0)
{
ListBox1.DataSource = res.ToList();
ListBox1.DataTextField = "tripdetails";
ListBox1.DataValueField = "ReservationID";
ListBox1.DataBind();
ListBox1.SelectedIndex = 0;
=> PaymentDS.WhereParameters[0].DefaultValue =
res.First().ReservationID.ToString();
}
}
protected void ListBox1_SelectedIndexChanged(object sender,
EventArgs e)
{
=> PaymentDS.WhereParameters[0].DefaultValue =
ListBox1.SelectedValue;
}
Thanks for the DefaultValue of Hoge Parameter is set to 0, in the other situation, paymentsListView is cleared automatically.
I think that your program is intrinsically correct, and this is a bug of Micorosoft.
This book is really wonderful!
Thanks.
|
Ryohsuke Fujioka |
Oct 17, 2009 |
Printed |
Page 308
last two lines on page |
On page 308 the lines
Imports BAGA.BreakAwayModel
and
using BAGA.BreakAwayModel;
should be
Imports BAGA
and
using BAGA;
|
BillHyde |
Aug 24, 2009 |
Printed |
Page 309
Figure 12 - 5 |
I think Figure 12-6 is the wrong screen capture. Its showing the mapping for the OLD "FK_Customers_Activities" association mapping that was originally established in the EDM. The new association mapping, as shown in Figure 12-5, should be named "ActivityCustomer".
The reason this matters is that when one attempts Step 4 on page 308, the mapping details view will show Activity and Customer tables, not Activities and Customers tables. This is confusing because there are no Activity or Customer tables in the store. So is the mapping NOT using table names, but rather entity names due to the inheritance, or something???
Also, to get the properties dialog settings displayed in Figure 12-5, one can drag the Association Tool from Activity to Customer, instead of dragging the Association Tool from Customer to activity as explained in Step 1 on page 308. Dragging the Association Tool from Customer to Activity wil give you an association named CustomerActivity, not ActivityCustomer. While I don't suppose it really matters, confusion arrises here.
In short, pages 308 and 309 could use some revisiting.
Thank you.
|
Bob Bedell |
Nov 01, 2009 |
Printed |
Page 316
2nd numbered list - creating NonCustomer |
On page 316 in the steps of creating the NonCustomer entity, there should be a mention that when one drags an entity from the toolbox to the design surface a property called "id" is created. This must be deleted prior to running the application or an exception noting a mapping error will be generated.
|
BillHyde |
Aug 24, 2009 |
Other Digital Version |
338
2nd paragraph |
In the second paragraph giving instructions for creating the entity data model for the simple POCO example, there is this sentence:
"Name the EntityContainer POCOEntities and select all tables".
If all the the tables and subsequent directions are followed, the example won't run. If only the Contact and Address tables are selected for the model, then after following the subsequent directions, the example runs fine. Bringing in all the tables brings in many more navigation properties than are covered in the example.
GREAT book, by the way!
-Barry
|
Barry Dieser |
Feb 22, 2012 |
Printed |
Page 340
C# code example |
In the 'Using Complex Types' section, the following line of code won't compile:
AddressDetail addressDetail = contact.Addresses[0].Detail;
I get:
Cannot apply indexing with [] to an expression of type 'System.Data.Objects.DataClasses.EntityCollecton<BAModel.Address>'
So I went with:
AddressDetail addressDetail = contact.Addresses.Take(1).FirstOrDefault().Detail;
Works OK.
The second to last line of the C# code has:
contact.Addresses(0).Detail = newAD;
Sould be brackets instead of parentheses in C#, shouldn't it, but neither compile.
|
Bob Bedell |
Nov 01, 2009 |
Printed |
Page 345
Example 13-7 |
The code is assumed to fix the two-way relation between Address and Contact. But when the address is re-linked to a different contact, for example by calling
address.Contact = contact1;
address.Contact = contact2;
both contacts will have the address listed and the object invariant is compromised.
This can be prevented by either checking for address._contact == null at the start of both Contact.AddAddress() and Address.set_Contact().
|
Arthur van Dongen |
Oct 07, 2011 |
Printed |
Page 363
Example 13-2 |
The cumulative walk-through approach seems to be causing code to break more and more frequently the deeper one gets into the book.
In the section on page 362 "Query Stored Procedures and Inherited Types" the text reads: "The CustomersWhoTravelledinDateRange stored procedure returns all of the appropriate fields to match up with the Customer type."
Unfortunately it doesn't, because when we inherited Customer from Contact in the previous chapter, we changed the Customer TimeStamp field name to custTimeStamp to avoid a naming collision with the TimeStamp field in the Contact entity.
So when you run the code in 13-2, you get:
"The data reader is incompatible with the specified 'BAModel.Customer'. A member of the type, 'custTimeStamp', does not have a corresponding column in the data reader with the same name."
It was my understanding that the book, going forward, was going to use cumulative changes to the model, though its 'kinda hard to follow when these changes are supposed to be retained and when they are supposed to be discarded. The sentence or two indicating this is often easy to overlook. It would be nice if the code download contained more versions of the model as it is supposed to exist at various stages of the book, given that a lot of people (like me) are probably creating different copies of the model for different topics to keep functioning versions intact.
|
Anonymous |
Nov 03, 2009 |
Printed |
Page 367
Example 14-1 |
When using the download from Chapter 8 for the BreakAwayModel with this section of code I receive an error on context.SaveChanges():
The conversion of a datetime2 data type to a datetime data type resulted in an out-of-range value.
It appears that without setting:
newCust.AddDate = (some DateTime variable)
newCust.ModifiedDate = (another DateTime variable)
I receive this error because they were set as Nullable = false.
|
Anonymous |
Aug 02, 2011 |
Printed |
Page 377
Example13-9 |
The UnpaidReservations DefiningQuery walk-through in Chapter 13 isn't implemented correctly. However, the Chapter 14 model contains a correct implementation of the UnpaidReservations DefiningQuery. If you run the Example 13-8 code againt the Chapter 14 model, you will get the correct output.
Caveat: In the Chapter 14 model I unzipped, the Activity entity was missing the Catagory property. I needed to add the Category scalar property to the Activity entity, then map it to the Activities.Category property in the store Activity table. Then everything built and ran fine.
|
Bob Bedell |
Nov 05, 2009 |
Printed |
Page 431
Example 14-28 |
Ran into some glitches with the Deleting Reservations logic for the UpdateCustomer method.
The first is a small code error, the second is some weird databinding behavior.
First, in the WPF service UpdateCustomer method, the following is given for the portion of the method that deletes Reservations from the reservation delete list:
var resid = cust.ReservationsToDelete[0];
it should be:
var resid = cust.ReservationsToDelete[resi];
The former will only delete the first reservation in the list; the latter will delete multiple reservations in one call to UpdateCustomer.
Second, in the client, the DelRes_Click calls ShowReservations() to refresh the reservations list box. Works fine for comboBox1_SelectedIndexChanged and AddRes_Click. For some odd reason, when calllled from DelRes_Click, instead of diplaying reservation TripDetails, the listbox diaplys:
Chapter14ClientCS.BAWCFService.Reservation
Chapter14ClientCS.BAWCFService.Reservation
Chapter14ClientCS.BAWCFService.Reservation
- databinding's default behavior when it calls an object's ToString() method, and ToString() isn't overridden.
I fixed it by binding the listbox's DataSource property first, then binding ValueMember and DisplayMember:
listBox1.DataSource = _currentCustomer.Reservations;
listBox1.ValueMember = "ReservationID";
listBox1.DisplayMember = "TripDetails";
instead of:
listBox1.ValueMember = "ReservationID";
listBox1.DisplayMember = "TripDetails";
listBox1.DataSource = _currentCustomer.Reservations;
If anyone has an explanation for that one, I'd love to here it on this book's forum.
|
Bob Bedell |
Nov 07, 2009 |
Printed |
Page 458
Last Paragraph |
"This is why these extra entries exist - one for Contact, one for the related Trip, and one for the UnpaidReservtion entity (which you created in Chapter 13)."
It appears that only TWO extra entries exist. There isn't one for the UnpaidReservation entity.
It appears that the placeholder entries are only created in cases where the Reservation entity is on the 'Many' side of a relationship.
So there is a key into the Contacts and Trips entity sets, but not to the Payments or UnpaidReservations entity sets, where the Reservation entity is on the '1' or '1..0' side of the relationship.
I'm using the Chapter 14 version of the model.
|
Bob Bedell |
Nov 08, 2009 |
Printed |
Page 545
Example 17-22 |
Missing a cast.
EntityKey currRelEndA = relEntry.CurrentValue[0] as EntityKey;
EntityKey currRelEndB = relEntry.CurrentValue[1] as EntityKey;
|
Bob Bedell |
Nov 14, 2009 |
Printed |
Page 561
Example 17-41 Creating a list of navigation property names |
There is no need for this list.
We can work directly with the ReadOnlyMetadataCollection returned by EntityType.NavigationProperties.
private static string BuildSingleEntityQuery(string entityReference,
string entityCollection,
int entityId,
MetadataWorkspace metadataWorkspace)
{
string containerName = metadataWorkspace.GetItems<EntityContainer>(DataSpace.CSpace)
.First().Name;
string namespaceName = metadataWorkspace.GetItems<EntityType>(DataSpace.CSpace)
.First().NamespaceName;
EntityType entityInfo = metadataWorkspace.GetItem<EntityType>(
namespaceName + "." + entityReference, DataSpace.CSpace);
// Get navigation properties.
ReadOnlyMetadataCollection<NavigationProperty> navigationProperties =
entityInfo.NavigationProperties;
string singleKeyName = entityInfo.KeyMembers[0].Name;
// Build the eSQL string.
StringBuilder eSqlQuery = new StringBuilder();
eSqlQuery.Append("SELECT entity");
// Add each navigation property to the projection.
foreach (var name in navigationProperties)
{
eSqlQuery.Append(", entity." + name);
}
eSqlQuery.Append(" FROM " + containerName.Trim() + "." + entityCollection + " AS entity");
eSqlQuery.Append(" WHERE entity." + singleKeyName + " = " + entityId);
return eSqlQuery.ToString();
}
|
Bob Bedell |
Nov 15, 2009 |
Printed |
Page 711
Top of Page Code |
Hello,
Custom property setters on the Customer are being used for the Primary and Secondary ID's of the Activities and Destinations. If there were no PrimaryActivity, would the PrimaryActivity always be null? If so could we do the following within the PrimaryActivityID property of the Customer:
if(PrimaryActivity == null)
instead of:
if (PrimaryActivityReference.EntityKey.EntityKeyValues.Count() > 0)
Perhaps the best approach is to use the longer code. But I'm always looking for ways to streamline, while not adding bugs.
Thanks,
Mark
|
Mark Phillips |
Jun 12, 2009 |