WIP/REF: BlockManager.setitem_blockwise
Posting largely for discussion with @phofl.

Motivations:

1) Try to end up with fewer code paths for setitem so that we can ensure consistent inplace/view/copy behavior (xref #38896)
2) Simplify (ATM this does not simplify things)
3) Perf: iterating over blocks instead of columns may save some copies (though doing the Index.intersection calls may go the other way) (havent done any profiling yet)

Non-trivial overlap with #39044.
Some of this would be simplified by #39163.
No logical overlap with #39266, but will require rebase.

Hello @jbrockmendel! Thanks for opening this PR. We checked the lines you've touched for [PEP 8](https://www.python.org/dev/peps/pep-0008) issues, and found:

* In the file [`pandas/core/arrays/datetimelike.py`](https://github.com/pandas-dev/pandas/blob/604f796f9a78d572ec784334f862a1a6d2fbc7ee/pandas/core/arrays/datetimelike.py):

> [Line 619:89](https://github.com/pandas-dev/pandas/blob/604f796f9a78d572ec784334f862a1a6d2fbc7ee/pandas/core/arrays/datetimelike.py#L619): [E501](https://duckduckgo.com/?q=pep8%20E501) line too long (91 > 88 characters)



* In the file [`pandas/core/frame.py`](https://github.com/pandas-dev/pandas/blob/604f796f9a78d572ec784334f862a1a6d2fbc7ee/pandas/core/frame.py):

> [Line 3222:89](https://github.com/pandas-dev/pandas/blob/604f796f9a78d572ec784334f862a1a6d2fbc7ee/pandas/core/frame.py#L3222): [E501](https://duckduckgo.com/?q=pep8%20E501) line too long (104 > 88 characters)











 Is there a specific place where I can be of help? Mostly just want to keep you in the loop on what i have in mind since you're working on similar parts of the code. @phofl this fails the test added in #39280.  Thoughts on an appropriate fix?

(a branch that only has the edits to `DataFrame._setitem_array` has the same failure) Not per se a fix, but I had similar difficulties in #39341 

We have to account for duplicate column names in these checks. Maybe using get_indexer_for or something like that if there is a faster alternative. Simply comparing the lenght does not work with duplicates You could use 
```
if self.columns.is_unique:
    len_key = len(key)
else:
    len_key = len(self.columns.get_indexer_non_unique(key))
if len(value) != len_key:
    raise ValueError("Columns must be same length as key")
```

as a helper functions for both len(value) != len(key) checks. Test will keep failing because the column is now cast to integer, but this is good since this is consistent with other setitem cases. If you like I could implement this in #39341. I am dispatching to the else block there right now, since this does the trick currently. mothballing