Pergunta

Agora que o LINQ to SQL é um pequeno mais maduro, gostaria de saber alguma técnica que as pessoas estão usando para criar uma solução de n camadas usando a tecnologia, porque não me parece tão óbvio.

Foi útil?

Solução

O LINQ to SQL realmente não tem uma história de n camadas que eu tenha visto, já que os objetos que ele cria são criados na classe com o resto, você realmente não tem um assembly que possa referenciar bem. algo como serviços da Web, etc.

A única maneira que eu realmente consideraria é usar o datacontext para buscar dados e, em seguida, preencher um modelo de dados intermediário, passando-o e referenciando-o em ambos os lados, e usando-o no lado do cliente - depois repassando-os e empurrando o dados de volta para um novo Datacontext ou atualizando linhas de forma inteligente depois de recuperá-los.

Isso se eu estiver entendendo o que você está tentando dizer :\

Fiz a mesma pergunta a ScottGu em seu blog quando comecei a examiná-lo - mas não vi um único cenário ou aplicativo disponível que use LINQ to SQL dessa maneira.Sites como o Storefront de Rob Connery estão mais próximos do fornecedor.

Outras dicas

Hum, Rockford Lhotka triste, que LINQ to SQL é uma tecnologia maravilhosa para buscar dados do banco de dados.Ele sugere que depois eles deverão ser vinculados para "alcançar objetos de domínio" (também conhecidos como.objetos CSLA).

Sério, o LINQ to SQL tinha suporte para arquitetura de n camadas, veja DataContext.Update método.

Você pode querer dar uma olhada no Estrutura de entidade ADO .Net como uma alternativa ao LINQ to SQL, embora também suporte LINQ.Acredito que o LINQ to SQL foi projetado para ser bastante leve e simples, enquanto o Entity Framework é mais pesado e provavelmente mais adequado em grandes aplicativos corporativos.

OK, vou me dar uma solução possível.

Inserções/atualizações nunca foram um problema;você pode agrupar a lógica de negócios em um método Salvar/Atualizar;por exemplo.

public class EmployeesDAL
{
    ...
    SaveEmployee(Employee employee)
    {
        //data formatting
        employee.FirstName = employee.FirstName.Trim();
        employee.LastName = employee.LastName.Trim();

        //business rules
        if(employee.FirstName.Length > 0 && employee.LastName.Length > 0)
        {
            MyCompanyContext context = new MyCompanyContext();

            //insert
            if(employee.empid == 0)
             context.Employees.InsertOnSubmit(employee);
            else
            {
              //update goes here
            }

            context.SubmitChanges();


        }
        else 
          throw new BusinessRuleException("Employees must have first and last names");
     }
 }

Para buscar dados, ou pelo menos buscar dados provenientes de mais de uma tabela, você pode usar procedimentos armazenados ou visualizações porque os resultados não serão anônimos, então você pode retorná-los de um método externo.Por exemplo, usando um processo armazenado:

    public ISingleResult<GetEmployeesAndManagersResult> LoadEmployeesAndManagers()
    {
        MyCompanyContext context = new MyCompanyContext();

        var emps = context.GetEmployeesAndManagers();

        return emps;
    }

Sério, o LINQ to SQL tinha suporte para arquitetura de n camadas, consulte o método DataContext.Update

Parte do que li sugere que a lógica de negócios agrupa o DataContext - em outras palavras, você agrupa a atualização da maneira sugerida.

Da maneira como tradicionalmente escrevo objetos de negócios, geralmente encapsulo os "métodos de carregamento" no BO;então eu poderia ter um método chamado LoadEmployeesAndManagers que retorna uma lista de funcionários e seus gerentes imediatos (este é um exemplo inventado).Talvez seja só eu, mas no meu front-end prefiro ver e.LoadEmployeesAndManagers() do que alguma instrução LINQ longa.

De qualquer forma, usando LINQ provavelmente seria algo assim (não verificado quanto à correção da sintaxe):

var emps = from e in Employees
                join m in Employees
                on e.ManagerEmpID equals m.EmpID
                select new
                          { e,
                            m.FullName
                          };

Agora, se entendi as coisas corretamente, se eu colocar isso, digamos, em uma biblioteca de classes e chamá-lo do meu front-end, a única maneira de retornar isso é como um IEnumerable, então perco minha forte qualidade de digitação.A única maneira de retornar um objeto fortemente digitado seria criar minha própria classe Employees (mais um campo de string para o nome do gerente) e preenchê-la com os resultados da minha instrução LINQ to SQL e depois retorná-la.Mas isso parece contraintuitivo...o que exatamente o LINQ to SQL me comprou se eu tivesse que fazer tudo isso?

Acho que posso estar vendo as coisas de maneira errada;qualquer esclarecimento seria apreciado.

"a única maneira de retornar isso é como um IEnumerable, então perco minha forte digitação"

isso está incorreto.Na verdade, sua consulta é fortemente digitada, é apenas um tipo anônimo.Acho que a consulta que você deseja é mais parecida com:

var emps = from e in Employees
            join m in Employees
            on e.ManagerEmpID equals m.EmpID
            select new Employee
                      { e,
                        m.FullName
                      };

O que retornará IEnumerable.

Aqui está um artigo Eu escrevi sobre o assunto.

Linq-to-sql é um ORM.Isso não afeta a maneira como você projeta um aplicativo de N camadas.Você o usa da mesma forma que usaria qualquer outro ORM.

@liammclenan

O que retornará IEnumerable....Linq-to-sql é um ORM.Isso não afeta a maneira como você projeta um aplicativo de N camadas.Você o usa da mesma forma que usaria qualquer outro ORM.

Então acho que ainda estou confuso.Sim, Linq-to-Sql é um ORM;mas, pelo que sei, ainda estou sobrecarregando meu código front-end com instruções de tipo sql embutidas (linq, não sql....mas ainda sinto que isso deve ser abstraído do front-end).

Suponha que eu envolva a instrução LINQ que estamos usando como exemplo em um método.Pelo que sei, a única maneira de devolvê-lo é desta forma:

public class EmployeesDAL
{
    public IEnumerable LoadEmployeesAndManagers()
    {
            MyCompanyContext context = new MyCompanyContext();

            var emps = from e in context.Employees
            join m in context.Employees
            on e.ManagerEmpID equals m.EmpID
            select new
                      { e,
                        m.FullName
                      };

            return emps;
    }

}

No meu código front-end, eu faria algo assim:

EmployeesDAL dal = new EmployeesDAL;
var emps = dal.LoadEmployeesAndManagers();

É claro que isso retorna um IEnumerable;mas não posso usar isso como qualquer outro ORM como você diz (a menos, é claro, que eu entenda mal), porque não posso fazer isso (novamente, este é um exemplo inventado):

txtEmployeeName.Text = emps[0].FullName

Isso é o que eu quis dizer com "Eu perco a bondade forte e digitada". Acho que estou começando a concordar com Crucible;que o LINQ-to-SQL não foi projetado para ser usado dessa maneira.Novamente, se não estou vendo as coisas corretamente, alguém me mostre o caminho :)

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