Pergunta

Espero que o título e o texto a seguir sejam claros, não estou muito familiarizado com os termos corretos; portanto, corrija -me se eu entender algo errado. Estou usando o LINQ ORM pela primeira vez e estou me perguntando como abordar o seguinte.

Diga que tenho duas tabelas de dB:

User
----
Id
Name


Phone
-----
Id
UserId
Model

O gerador de código LINQ produz várias classes de entidade.

Escrevo então minhas próprias aulas e interfaces que enrolam essas classes LINQ:

class DatabaseUser : IUser
{
    public DatabaseUser(User user)
    {
        _user = user;
    }

    public Guid Id 
    {
        get { return _user.Id; } 
    }

    ... etc
}

até agora tudo bem.

Agora é fácil o suficiente encontrar telefones de usuários de Phones.Where(p => p.User = user) Mas certamente os compositores da API não precisam escrever suas próprias consultas LINQ para obter dados, para que eu envolva essa consulta em uma função ou propriedade em algum lugar.

Portanto, a pergunta é, neste exemplo, você adicionaria uma propriedade de telefones à iuser ou não?

Em outras palavras, minha interface deve estar modelando especificamente meus objetos de banco de dados (nesse caso, os telefones não pertencem a Iuser), ou eles estão simplesmente fornecendo um conjunto de funções e propriedades que estão conceitualmente associadas a um usuário (nesse caso faz)?

Parece desvantagens para ambas as visões, mas estou me perguntando se existe uma abordagem padrão para o problema. Ou qualquer palavra geral de sabedoria que você possa compartilhar.

Meu primeiro pensamento foi usar métodos de extensão, mas na verdade isso não funciona neste caso.

Foi útil?

Solução

Tive algumas experiências terríveis tentando abstrair as entidades Linqtosql por trás das interfaces. Faz um tempo atrás, mas de memória o principal problema era que ele quebra totalmente as associações. Por exemplo, se você tem um Customer -> Order relacionamento, você acaba expondo -o como um ICustomer, com uma coleção de IOrders, o que significa que Customer tem que fazer algum mapeamento estranho para lançar sua coleção interna de Order objetos como IOrders.

Então você deve assumir que quando um IOrder é passado de volta, que podemos lançá -lo para um Order. Caso contrário, o Linqtosql não pode lidar com isso, mas isso derrota o ponto de ter a interface lá em primeiro lugar.

Eu recomendo fortemente que você não tente abstrair demais as classes de entidade, o Linqtosql não coloca nenhuma mágica real nelas, o Datacontext lida com seu ciclo de vida de persistência, para que eles permaneçam testáveis.

Os aspectos que eu gostaria de me esconder atrás de uma interface seriam as interações com o DataContext, por exemplo, usando classes de estilo repositório:

public interface IPhoneRepository 
{
    IEnumerable<Phone> GetPhonesForUser(User user);
}

public class L2SPhoneRepository : IPhoneRepository
{
    private readonly MyDataContext context;

    public L2SPhoneRepository(MyDataContext context)
    {
        this.context = context;
    }

    public IEnumerable<Phone> GetPhonesForUser(User user)
    {
        return context.Phones.Where(p => p.User == user);
    }
}

Outras dicas

Sua interface deve modelar como você gostaria que os objetos fossem usados. Como você está tentando abstrair, o consumidor não deve precisar consultar o banco de dados. Se você faz uma propriedade ou uma chamada de função separada (ou seja, getphones ()), depende inteiramente de você. Como você está envolvendo completamente as coisas, precisará fazer algumas escolhas sobre o quão profundo/preguiçoso deseja carregar seus objetos.

Você deve adicionar a propriedade de telefones ao iuser e torná -la anulável; portanto, para um usuário que não possui telefone, será nulo.

Como você não deseja que os consumidores da API escrevam consultas, você deve implementar funções como getUser () .. etc.

Aqui está uma bela lista de artigos abt n-tier Application no ASP.NET

http://imar.spaanjaars.com/quickdocid.aspx?quickdoc=416

Costumo considerar o material relacionado ao LINQ2SQL como um detalhe de implementação do código de acesso a dados e, como a estrutura real do banco de dados, não deve necessariamente ser exposto a outras partes do sistema.

Se sua API for consumida por outras pessoas, deve ser coesa e fácil de usar e não desgaste por coisas que o consumidor não precisa saber. Se estou lidando com usuários e seus telefones, eu realmente não quero saber sobre dados de dados do DataContexts ou (UGH).

Além disso, mantendo a maior parte do seu código ignorante dos L2s e do banco de dados, você terá um teste mais fácil, fazendo mudanças no esquema (oh, então agora a tabela de usuários precisa manter um histórico de todas as alterações feitas) ou até alterar o ORM completamente .

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top