Question: I know \_\_r represents the lookup relationship. I want to use it in the following way. Why can I or can't I do this ? It compiles so it seems ok:

```
 Taste_Assessment__c wa = [Select id, Expiration_Date__c, 
       Opportunity__r.AccountId 
       from Taste_Assessment__c 
       where Opportunity__c =: oppid];

    if(validateOpportunity(wa.Opportunity__r)){

    }

    private static Boolean validateOpportunity(Opportunity opp){

     }

```

Answer: 
David beat me to the punch, but here's another way to visualize what's going on here.

```
Taste_Assessment__c wa = new Taste_Assessment__c(
    Id = <target record id>,
    Expiration_Date__c = Date.today(),
    Opportunity__r = new Opportunity(
        AccountId = <target account id>
    )
);

```

Provided that you replaced the `<target record id>` and `<target account id>` with appropriate values, this code would compile and ends up being functionally identical to what you get from your query.

It really is just an SObject inside of another SObject.
You can. In this situation, `Opportunity__c` is typed as an `Id`, and `Opportunity__r` is typed as an `Opportunity`. This pattern applies generally to child-to-parent lookup relationships.

For parent-to-child subqueries, you'll have, for example, `Account.Contacts` typed as a `List<Contact>`.

The sObject instances you get back work like any other, and you can make data updates and perform DML on them. However, performing DML on the parent (`Taste_Assessment__c`) won't do anything to persist the child sObjects.