Pergunta

Eu olhei sobre o padrão Repository e eu reconheci algumas idéias que eu estava usando no passado que me fez sentir bem.

No entanto, agora eu gostaria de escrever um aplicativo que usaria esse padrão Mas as classes I gostaria de ter a entidade dissociados do provedor de repositório.

Gostaria de criar várias montagens:

  1. um "Interfaces" assembléia que seria a sede interfaces comuns, incluindo a IRepository de interface
  2. um "Entidades" montagem que hospedam as classes de entidade como produto, Utilizador, Ordem e assim por diante. Este conjunto seria referenciado pelas "Interfaces" assembléia uma vez que alguns métodos retornaria tais tipos ou matrizes de-los. Também seria referenciado pela aplicação principal de montagem (como o Web Application)
  3. um ou provedor mais Repository montagem / conjuntos. Cada incluiria (pelo menos) uma classe que implementa a interface IRepository e seria trabalhar com um determinado armazenamento de dados. armazenamentos de dados pode incluir um SQL Server, um servidor Oracle, MySQL, arquivos XML, / serviços WCF Web e assim por diante.

Estudar LINQ to SQL que parece muito produtivo em termos de tempo necessário para implementar tudo parece bem até que eu descobrir a profunda dependência entre as classes geradas e da classe CustomDataContext.

Como posso usar LINQ to SQL em tal cenário?

Foi útil?

Solução

Eu não sei se isso é exatamente o que você quer, mas você pode querer dar uma olhada em código MVC Storefront de Rob Conery. Ele usa uma variante do padrão de repositório com um provedor LINQ. Ele mapeia o LINQ to SQL objetos para objetos de domínio e retorna os objetos de domínio do provedor de repositório para uma camada de serviço que envolve o fornecedor que lhe permite trabalhar alguma lógica na dados retornados antes de atingir a camada de negócios.

MVC Storefront Webcasts
Código

Para mim parece que você quer que os provedores de voltar DTOs e então você deseja mapear os DTOs para os objetos de domínio na camada de repositório / serviço. Se este for o caso, você pode mapear o seu provedor LINQ to SQL para os DTOs, tê-lo devolvê-los, em seguida, mapear os DTOs para objetos de domínio na camada de repositório / serviço. Isso deve funcionar muito bem, mas pode se tornar tedioso como você agora teria 2 camadas de mapeamento.

Neste caso, você teria: ProductService, que leva uma IProductRepository. Ela evoca métodos no IProductRepository para voltar a sua DTOs. Em seguida, mapeia os DTOs para os objetos de negócios reais e as retorna para o código de chamada.

Outras dicas

Você pode criar um arquivo XML externo mapeamento do banco de dados para qualquer classe:

 <?xml version="1.0" encoding="utf-8"?>
 <Database Name="DbName" 
           xmlns="http://schemas.microsoft.com/linqtosql/dbml/2007">
    <Table Name="DbTableName">
       <Type Name="EntityClassName" >
           <Column Name="ID" Type="System.Int64" Member="Id"
                   DbType="BigInt NOT NULL IDENTITY" IsPrimaryKey="true"
                   CanBeNull="false" />
           <Column Name="ColumnName" Type="System.String" Member="PropertyA"
                   DbType="VarChar(1024)" CanBeNull="true" />
       </Type>
    </Table>
 </Database>

E, em seguida, passar o XML para uma classe DataContext:

 using (var cn = GetDbConnection())
  { var mappingSrc = XmlMappingSource.FromReader(xmlReader);

    using (var db = new DataContext(cn, mappingSrc))
     { var q = from entity in db.GetTable<EntityClassName>()
               where entity.PropertyA = "..."
               select entity.ID;
     }
  }

Eu encontrei um fantástico blog (com lotes de código bom) sobre isso aqui: http://iridescence.no/post/Linq-to-Sql-Programming-Against-an-Interface-and-the-Repository-Pattern.aspx

Eu acho que você quer apoio POCO (Plain Old CLR Objects). LINQ to SQL possui um adaptador chamado Close2Poco .

Mas eu aconselho fazer a mudança para Entity Framework, no momento em que eles também têm um POCO adaptador , mas em v2 seu esperado para ser apoiado fora da caixa .

Você não tem que usar o LINQ to SQL código gerado, você pode decorar suas próprias classes com as ColumnAttributes necessárias ou usar um arquivo de mapeamento XML externo.

A maneira mais simples seria a de dissociar suas entidades do datacontext:. Carregar a entidade necessária, dissociar-lo do DataContext, usá-lo da maneira que quiser, mais tarde usar Anexar () para acoplar com um DataContext para salvar

Infelizmente LINQ não tem nenhum método para entidades dissociar a partir de um datacontext, mas você pode apenas cloná-los, que funciona muito bem. maneira mais simples seria algo como isto:

public static T CloneEntity<T>(T source)
{
  DataContractSerializer dcs = new DataContractSerializer(typeof(T));
  using (Stream stream = new MemoryStream())
  {
    dcs.WriteObject(stream, source);
    stream.Seek(0, SeekOrigin.Begin);
    return (T)dcs.ReadObject(stream);
  }
}

Eu fiz algo semelhante com o WCF

1 Em seu DBML, definir o seu modo de serialização para unidirecional

2 colunas definir todos em suas tabelas para UpdateCheck = false

3 Escrever o seu serviço de algo como o seguinte:

   public class Service1 : IService1
    {
        public Company GetCompany(int companyId)
        {
            using (DataClasses1DataContext dc = new DataClasses1DataContext())
            {
                return (from c in dc.Companies where c.CompanyId == companyId select c).Single();
            }
        }

    public void SaveCompany(Company company)
    {
        using (DataClasses1DataContext dc = new DataClasses1DataContext())
        {
            dc.Companies.Attach(company, true);
            dc.SubmitChanges();
        }
    }

    public void InsertCompany(Company company)
    {
        using (DataClasses1DataContext dc = new DataClasses1DataContext())
        {
            dc.Companies.InsertOnSubmit(company);
            dc.SubmitChanges();
        }
    }
}

4 Adicione uma referência de serviço

Não é exatamente o mesmo cenário, mas estou trabalhando para criar uma ferramenta personalizada que, com base em um arquivo XML irá gerar um modelo OO. Minha abordagem é usar LINQ to SQL por trás da cena e desde que eu estou gerando o código automaticamente seria fácil de usar outro mecanismo para fonte de dados MySQL digamos do let. Desde que não é suportado pelo LINQ to SQL que você terá que escrever o código de acesso de dados manualmente, mas o código do cliente que vai usar o modelo OO vai mudar de forma alguma.

Poderia suas classes de entidade implementar etc. interfaces de IProduct, IUSER, IOrder que seriam declarados em seus "Interfaces" montagem? Desta forma, as referências de interface IRepository apenas as interfaces de objetos de negócios (ou seja, retorna coleções de IProduct etc.) e os "Interfaces" montagem é dissociados de seus outros conjuntos específicos de implementação.

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