Вы можете создать фабричный метод:
public static Profile ReadProfile()
{
var query = from u in db.Users.Where(r => r.user_id == user_id )
select u;
return query.First();
}
Это гораздо более предпочтительный путь с разных точек зрения. Прежде всего, это не обычная конструкция. Пользователи вашего класса Profile не могли ожидать каких-либо операций, связанных с базой данных, во время обычного вызова конструкторов по умолчанию, и использование фабричного метода является более понятным способом представления вашего намерения. Во-вторых, это упрощает дальнейшие изменения. Например, еще более предпочтительным способом реализации уровня доступа к данным (a.k.a. DAL) является создание нового класса (или набора классов), который бы инкапсулировал все операции, связанные с базой данных.
Например, вы можете создать отдельный интерфейс:
interface IProfileRepository
{
Profile ReadProfile();
}
А затем создайте свой конкретный репозиторий:
class ProfileRepository : IProfileRepository
{
public Profile ReadProfile() { .. implementation skipped .. }
}
В этом случае вы разделяете свою логику еще больше. И это позволяет вам просто «заменить» ваши реальные классы (например, ProfileRepository) на «поддельные» классы, которые возвращают «поддельные» объекты.
Этот метод называется " mocking " и особенно полезен для создания модульных тестов, в которых не используются никакие внешние ресурсы, такие как базы данных.