Indirection
---

There is a significant difference between an entity and a viewmodel. You've already pointed one out: entities have no inherent requirements of linked entities to exist/be loaded, but in this case your viewmodel does.  
Since your viewmodel is the one who causes this requirement to exist, putting it in the viewmodel is _precisely_ the place it should be enshrined.

> but this introduces a lot of time wasting by essentially copying the data's structural definition from the Entity type to the View-Model type

This is the age-old mantra of bad practice justifications. I want to cut this corner because I it's a waste of time. Or, more aptly put, anything that takes longer than the shortest thing I can think of is therefore a needless waste of time.

Not only should you take the time and effort to separately declare the structure of an entity and a viewmodel, **regardless of any similarities they may share**; but you also seem to have skipped one or two extra layers of indirection, i.e. the database DTO and business DTO.

This is where we get to differing opinions on where the bar is set. Some advocate that you always need all layers. Some advocate a more contextual approach. But I think you'll get a near unanimous agreement that entities and viewmodels are the absolute barebones requirements for indirection. I would personally suggest having at least one additional layer of indirection in there, but that's a contextual inference on my part about the scope and complexity of your application.

> if the View Model class simply embeds Entity Types (which is fine when the View Model is not being used in a `<form>`!)

I have no idea where you got this idea, I have never heard of this argument before, and I disagree with it wholly. 

Whether or not your data ends up in a form is completely irrelevant. Any data you send to a browser gets sent as HTML (since you're talking about `<form>`) and inherently loses all connection to the entity that was the source of the data. 

If the user ends up making a second request, this time containing some form data that just happens to be the same as the entity you used for the first request, that's a completely separate request, with its own scope, and no bearing on the entity from the first event.

> which doesn't "scale" when an application could have hundreds of different views all with similar requirements

We've now hit on the second mantra of bad practice justification. I could decide to _not_ cut this corner, but there are many corners ahead, and not cutting any corner is a waste of time.

Every class exists because it has its own defined purpose. Different purpose? Different class. Same purpose? Same class.

Note the difference between a class' *purpose* and its *structure*. Two classes may exist with the exact same class structure, but each serving a different purpose (DTOs are a common example here). Overzealous refactoring may lead you to condense these two classes together as their structure is the same, but that is a bad practice mistake. Each class serves its own purpose and therefore each class has its own reason to exist.

**The size of an application is not justification for cutting corners**. There is not a single good practice rule that has a "unless you have a lot of classes" kind of exception to it.

Just imagine if you find out that the contractor building your house skipped parts of the building plan "because they have a lot of houses to build". The building plan is to be followed, regardless of how many building plans exist.  
"I had to do many" is just not a valid argument. But often, we only care about that when we personally suffer from the corner-cutting, rather than when we're the one doing it for our own benefit (i.e. less work).

> An example based on the scenario above would involve a new type struct `CustomerWithLoadedOrders`

You've basically just reinvented the DTO.

It's interesting to see that you first balk at the thought of having to develop a separate type (think of the work it will cause), and then solve the problem by... developing a separate type.

Credit where credit is due, you have written a great question here. You've elaborated on all the considerations and your thought process. You've done your due diligence and I would definitely not accuse you of not thinking things through.  

But your eloquence means you're clever, and **clever is dangerous in the field of clean coding**. Clean code is boring, but boring is good. Being clever can become your undoing, when it leads you to try and cleverly work around a commonly accepted feature, somehow end up doing it anyway (just with a different name), and then not realize that you've done the same thing you were avoiding, and it's now needlessly more complex because its atypical and therefore harder to understand.

Take this from me, someone who is infinitely attracted to clever solutions, that the unsexy truth is that good practice and cleverness rarely go hand in hand. There's a reason why [Code Golf](https://codegolf.stackexchange.com/) has zero overlap with any good practice principle.

------

Immutability
----

> And this immutable View Model for a page

    class CustomerOrderPageViewModel : IPageViewModel
    {
        public Customer CustomerSubject { get; }
    }

If `Customer` is mutable, then given its class definition, `CustomerOrderPageViewModel` is also mutable, since you can do things like this:

    var model = new CustomerOrderPageViewModel(new Customer());
    
    model.CustomerSubject.Name = "I can totally change this";

Immutability can only be built on immutability. An interesting discussion appears when you consider if `Customer` had not been publically accessible from the viewmodel, e.g.:

    class CustomerOrderPageViewModel : IPageViewModel
    {
        private readonly Customer customer;
        public Customer CustomerName => this.customer.Name;
    }

Is this immutable? You cannot alter a `CustomerOrderPageViewModel` instance, so it must be immutable, right? 

However, it's still possible to indirectly alter the data contained in this `CustomerOrderPageViewModel` instance:

    var customer = new Customer() { Name = "Original" };

    var model = new CustomerOrderPageViewModel(customer);
    var modelName_1 = model.CustomerName;

    customer.Name = "Different";
    var modelName_2 = model.CustomerName;

    var isImmutable = modelName_1 == modelName_2; // false

If the same property of the same instance can yield different values, then the object is by definition mutable.

[This answer](https://stackoverflow.com/a/34109446/952296) explores the issue better than I can, but the gist of it is that the only way to have an immutable class that is based on a mutable reference type (i.e. the entity) is to (a) obviously not expose any mutable types as properties and (b) **copy** all the needed data in the constructor, so that any future changes made to the instance of the mutable reference type no longer cause changes to the content of your immutable instance.

Note that when you do actually implement the indirection described above, and your viewmodels and entities are separate, then you can in fact achieve immutability easily here. I just wanted to point out that what you call immutability is not in fact immutability, because otherwise you are liable to repeat that mistake even if you were to add a layer of indirection.