This is a better approach I think.
(with-current-buffer (find-file-noselect "foo.el")
(goto-char (point-min))
(read (current-buffer)))
If you want to wrap this as you describe below, and excecute it, try this:
(defmacro my-read (fname)
`(progn
,(with-current-buffer (find-file-noselect fname)
(goto-char (point-min))
(read (current-buffer)))))
Both of these leave the file open.
Edit: The code above only reads one sexp, so it won't read the whole file unless it is wrapped in a single pair of parens. That is basically what your solution achieves below. This code below reads them all and closes the buffer. One issue with the code below is I had to wrap it in ignore-errors because read raises an error at the end of the file. I couldn't figure out a way to not get an error or handle that particular error.
(defmacro my-read (fname)
(let ((sexps '())
(sexp)
(buf (find-file-noselect fname)))
(with-current-buffer buf
(goto-char (point-min))
(ignore-errors
(while (setq sexp (read buf))
(message "%s" sexp)
(push sexp sexps))))
(kill-buffer buf)
`(progn
,@(reverse sexps))))
read
. Type[read]
into the SE search field, to see them.