Question

Maintenant que LINQ to SQL est un petit plus mature, j'aimerais connaître les techniques utilisées par les gens pour créer une solution à n niveaux utilisant la technologie, car cela ne me semble pas si évident.

Était-ce utile?

La solution

LINQ to SQL n'a pas vraiment d'histoire à n niveaux que j'ai vue, puisque les objets qu'il crée sont créés dans la classe avec le reste, vous n'avez pas vraiment d'assembly que vous pouvez bien référencer via quelque chose comme les services Web, etc.

La seule façon dont je l'envisagerais vraiment est d'utiliser le contexte de données pour récupérer des données, puis de remplir un modèle de données intermédiaire, de le transmettre et de le référencer des deux côtés, et de l'utiliser du côté client - puis de les renvoyer et de pousser le les données dans un nouveau Datacontext ou mettre à jour intelligemment les lignes après les avoir récupérées.

C'est si je comprends ce que vous essayez de dire :\

J'ai posé la même question à ScottGu sur son blog lorsque j'ai commencé à le consulter - mais je n'ai pas vu un seul scénario ou une seule application dans la nature qui utilise LINQ to SQL de cette manière.Des sites Web comme Storefront de Rob Connery sont plus proches du fournisseur.

Autres conseils

Hum, Rockford Lhotka triste, que LINQ to SQL est une technologie merveilleuse pour récupérer des données à partir d'une base de données.Il suggère qu'ils devront ensuite être liés pour "atteindre les objets du domaine" (aka.objets CSLA).

Sérieusement parlant, LINQ to SQL prenait en charge l'architecture à n niveaux, voir DataContext.Update méthode.

Vous voudrez peut-être examiner le Cadre d'entité ADO .Net comme alternative à LINQ to SQL, bien qu'il prenne également en charge LINQ.Je pense que LINQ to SQL est conçu pour être assez léger et simple, alors qu'Entity Framework est plus robuste et probablement plus adapté aux grandes applications d'entreprise.

OK, je vais me donner une solution possible.

Les insertions/mises à jour n'ont jamais été un problème ;vous pouvez envelopper la logique métier dans une méthode Save/Update ;par exemple.

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");
     }
 }

Pour récupérer des données, ou au moins pour récupérer des données provenant de plusieurs tables, vous pouvez utiliser des procédures stockées ou des vues car les résultats ne seront pas anonymes et vous pourrez donc les renvoyer à partir d'une méthode extérieure.Par exemple, en utilisant un processus stocké :

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

        var emps = context.GetEmployeesAndManagers();

        return emps;
    }

Sérieusement parlant, LINQ to SQL prenait en charge l'architecture à n niveaux, voir la méthode DataContext.Update

Une partie de ce que j'ai lu suggère que la logique métier encapsule le DataContext - en d'autres termes, vous encapsulez la mise à jour de la manière que vous suggérez.

La façon dont j'écris traditionnellement des objets métier, j'encapsule généralement également les "méthodes de chargement" dans le BO ;je pourrais donc avoir une méthode nommée LoadEmployeesAndManagers qui renvoie une liste des employés et de leurs supérieurs immédiats (il s'agit d'un exemple artificiel).Peut-être que c'est juste moi, mais dans mon front-end, je préfère voir e.LoadEmployeesAndManagers() plutôt qu'une longue instruction LINQ.

Quoi qu'il en soit, en utilisant LINQ, cela ressemblerait probablement à ceci (non vérifié pour l'exactitude de la syntaxe) :

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

Maintenant, si je comprends bien les choses, si je mets cela dans, par exemple, une bibliothèque de classes et que je l'appelle depuis mon front-end, la seule façon de le renvoyer est sous la forme d'un IEnumerable, donc je perds ma forte bonté typée.La seule façon pour moi de renvoyer un objet fortement typé serait de créer ma propre classe Employees (plus un champ de chaîne pour le nom du responsable) et de la remplir à partir des résultats de mon instruction LINQ to SQL, puis de la renvoyer.Mais cela semble contre-intuitif...qu'est-ce que LINQ to SQL m'a acheté exactement si je dois faire tout cela ?

Je pense que je vois peut-être les choses de la mauvaise façon ;toute illumination serait appréciée.

"la seule façon de renvoyer ceci est en tant que IEnumerable, donc je perds ma forte bonté typée"

c'est incorrect.En fait votre requête est fortement typée, c'est juste un type anonyme.Je pense que la requête que vous souhaitez ressemble davantage à :

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

Ce qui renverra IEnumerable.

Voici un article J'ai écrit sur le sujet.

Linq-to-sql est un ORM.Cela n’affecte pas la façon dont vous concevez une application à N niveaux.Vous l'utilisez de la même manière que vous utiliseriez n'importe quel autre ORM.

@liammclennan

Ce qui renverra IEnumerable....Linq-to-sql est un ORM.Cela n’affecte pas la façon dont vous concevez une application à N niveaux.Vous l'utilisez de la même manière que vous utiliseriez n'importe quel autre ORM.

Ensuite, je suppose que je suis toujours confus.Oui, Linq-to-Sql est un ORM ;mais pour autant que je sache, je remplis toujours mon code frontal d'instructions de type SQL en ligne (linq, pas sql...).mais je pense quand même que cela devrait être abstrait du front-end).

Supposons que j'encapsule l'instruction LINQ que nous avons utilisée comme exemple dans une méthode.Pour autant que je sache, la seule façon de le retourner est la suivante :

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;
    }

}

À partir de mon code frontal, je ferais quelque chose comme ceci :

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

Bien sûr, cela renvoie un IEnumerable ;mais je ne peux pas l'utiliser comme n'importe quel autre ORM comme vous le dites (à moins bien sûr que je comprenne mal), car je ne peux pas le faire (encore une fois, c'est un exemple artificiel) :

txtEmployeeName.Text = emps[0].FullName

C'est ce que je voulais dire par «Je perds la forte bonté dactylographiée». Je pense que je commence à être d'accord avec Crucible;que LINQ-to-SQL n'a pas été conçu pour être utilisé de cette manière.Encore une fois, si je ne vois pas les choses correctement, quelqu'un me montre le chemin :)

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top