Entity Framework e evitando o modelo de domínio anêmico

11

Em nossa lógica de negócios, ocasionalmente temos métodos definidos algo como isto:

User.ResetCourse(Course courseToReset)

O problema é que o usuário e o curso são objetos de proxy do Entity Framework. Isso significa que, quando atingimos as propriedades de navegação em Usuário ou Curso, isso pode causar um grande impacto no banco de dados, porque esses objetos não são IQueryable; portanto, ele os percorre normalmente.

Para resolver isso, alteramos a assinatura para:

User.ResetCourse(MyDBContext db, Course courseToReset)

Isso significa que podemos consultar diretamente o banco de dados para fazer as alterações necessárias de uma maneira eficiente, mas passar o contexto do Banco de Dados para um objeto de negócios parece tão errado.

Mais tarde, migramos para o usuário uma camada de serviço, o que significa que temos algo como:

CourseService.ResetForUser(Course courseToReset, User forUser)

Este serviço tem uma referência ao DBContext injetado na criação, mas agora nossos objetos de negócios são apenas sacos de dados sem comportamento (ou seja, um Modelo de Domínio Anêmico).

Como podemos evitar isso?

Steve
fonte
11
Parece que você acabou de perceber que os modelos de estrutura de entidade são na verdade DTOs e não um modelo de domínio. Você está realmente tentando fazer DDD? Caso contrário, provavelmente não importa.
Sr. Cochese
3
ADM além de serviços é uma boa arquitetura para muitas coisas
Ewan
2
@ JohnWu esse é um artigo muito tendencioso. Na verdade, ele contém uma versão "Strawman" de um modelo de domínio avançado, incluindo o padrão Active Record no exemplo avançado. Certamente, o Active Record não é defendido no DDD e, em geral, é uma má escolha para qualquer aplicativo complexo.
precisa saber é o seguinte

Respostas:

7

O problema é que você está usando objetos EF como objetos de domínio em primeiro lugar. Objetos EF são modelos de dados, NÃO modelos de negócios.

Você precisa declarar objetos de negócios que lhe dão a liberdade de fazer o necessário e, em seguida, recuperá-los e armazená-los em um repositório. Seu repositório mapeará as entidades EF para suas entidades comerciais. Objetos EF nunca devem ser usados ​​fora de seus repositórios.

TheCatWhisperer
fonte
0

Você provavelmente pode evitá-lo fazendo algo como:

CourseService.prepareForUserCourseReset(DBContext db);
User.reset();
Course.reset();
CourseService.completeUserCourseReset(DBContext db);

Ou algo nesse sentido, de qualquer maneira, se você entender minha tendência. Parece que a abordagem que você tem com a maneira que você descreveu está relacionada ao desempenho e não necessariamente à estrutura do domínio. Então, realmente, você deve considerar resolver o problema de desempenho na camada de serviço, mas pode manter o comportamento no domínio. Seria útil saber o que significa redefinir o Usuário / Curso neste contexto também se você quiser uma resposta melhor.

RibaldEddie
fonte