To answer #1 - when separating the domain model from the persistence model, change tracking is not a problem. The reason is that change tracking is more of a cross-cutting concern than a domain concern. The concern of a domain model is not to ensure that changes to itself are tracked.
The changes we want to track are typically the ones that we also persist. IOW, if, in the course of some processing, we change a property value and then change it back, there is no change to persist, which means there's also no change to track. So I'd lean toward change tracking as a behavior of the persistence, not the domain.
Edited:
Here's a note from Patters, Principles, and Practices of Domain-Driven Design:
Don't put dirty flags on domain objects
It might be tempting to put a flag on a domain object to signify that it has changed. The problem with this is that you are clouding the domain model with persistence concerns. Leave all change tracking to the unit of work and the repository.
For #2 - I don't have an open source example. But to start with, the separation between domain models and persistence models means ensuring that the persistence is abstracted, perhaps using the repository pattern.
If your domain models depend on a 'persistence ignorant' repository abstraction, like
public interface IRepository<T> where T : class
{
void Add(T item);
void Update(T item);
void Delete(T item);
void Get(RecordId id);
}
Then the implementation of that repository can map that T
to and from whatever persistence-specific model is needed, and the domain will never know that the persistence model even exists.
In order for this to happen, the domain needs to define its own repository interface rather than injecting one defined in some persistence library. That leaves the domain persistence agnostic and easier to test, and only the implementation(s) of that repository know about the details of the persistence.