Pregunta

Ahora que LINQ to SQL es un pequeño Más maduro, me gustaría conocer alguna técnica que la gente esté usando para crear una solución de n niveles usando la tecnología, porque no me parece tan obvio.

¿Fue útil?

Solución

LINQ to SQL realmente no tiene una historia de n niveles que yo haya visto, ya que los objetos que crea se crean en la clase con el resto, realmente no tienes un ensamblado al que puedas hacer referencia. algo así como servicios web, etc.

La única forma en que realmente lo consideraría es usar el contexto de datos para obtener datos, luego completar un modelo de datos intermediario, pasarlo y hacer referencia a él en ambos lados, y usarlo en el lado del cliente, luego pasarlos de regreso y empujar el datos nuevamente en un nuevo contexto de datos o actualizando filas de manera inteligente después de volver a recuperarlas.

Eso si entiendo a qué quieres llegar :\

Le hice a ScottGu la misma pregunta en su blog cuando comencé a verlo, pero no he visto un solo escenario o aplicación que use LINQ to SQL de esta manera.Los sitios web como Storefront de Rob Connery están más cerca del proveedor.

Otros consejos

Mmm, Rockford Lhotka Es triste que LINQ to SQL sea una tecnología maravillosa para recuperar datos de una base de datos.Sugiere que luego deberán vincularse para "alcanzar objetos de dominio" (también conocido como.Objetos CSLA).

Hablando en serio, LINQ to SQL tenía soporte para arquitectura de n niveles. DataContext.Actualización método.

Es posible que desee examinar el Marco de entidad ADO .Net como alternativa a LINQ to SQL, aunque también es compatible con LINQ.Creo que LINQ to SQL está diseñado para ser bastante liviano y simple, mientras que Entity Framework es más pesado y probablemente más adecuado en aplicaciones empresariales grandes.

Bien, me voy a dar una posible solución.

Las inserciones/actualizaciones nunca fueron un problema;puede envolver la lógica empresarial en un método Guardar/Actualizar;p.ej.

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 recuperar datos, o al menos recuperar datos que provienen de más de una tabla, puede utilizar vistas o procedimientos almacenados porque los resultados no serán anónimos, por lo que puede devolverlos desde un método externo.Por ejemplo, usando un proceso almacenado:

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

        var emps = context.GetEmployeesAndManagers();

        return emps;
    }

Hablando en serio, LINQ to SQL tenía soporte para arquitectura de n niveles. Consulte el método DataContext.Update.

Parte de lo que he leído sugiere que la lógica empresarial envuelve el DataContext; en otras palabras, envuelve la actualización de la forma que sugiere.

De la forma en que tradicionalmente escribo objetos comerciales, normalmente también encapsulo los "métodos de carga" en el BO;entonces podría tener un método llamado LoadEmployeesAndManagers que devuelva una lista de empleados y sus gerentes inmediatos (este es un ejemplo artificial).Tal vez sea solo yo, pero en mi interfaz prefiero ver e.LoadEmployeesAndManagers() que una declaración LINQ larga.

De todos modos, usando LINQ probablemente se vería así (sin verificar la corrección de la sintaxis):

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

Ahora bien, si entiendo las cosas correctamente, si pongo esto, digamos, en una biblioteca de clases y lo llamo desde mi interfaz, la única forma en que puedo devolverlo es como un IEnumerable, por lo que pierdo mi bondad de tipo fuerte.La única forma en que podría devolver un objeto fuertemente tipado sería crear mi propia clase Empleados (más un campo de cadena para el nombre del administrador) y completarlo con los resultados de mi declaración LINQ to SQL y luego devolverlo.Pero esto parece contrario a la intuición...¿Qué me compró exactamente LINQ to SQL si tengo que hacer todo eso?

Creo que podría estar viendo las cosas de manera equivocada;cualquier aclaración sería apreciada.

"La única forma en que puedo devolver esto es como IEnumerable, por lo que pierdo mi bondad de tipo fuerte"

Eso es incorrecto.De hecho, su consulta está fuertemente tipada, es solo de tipo anónimo.Creo que la consulta que deseas es más como:

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

Que devolverá IEnumerable.

Aquí está un artículo Escribí sobre el tema.

Linq-to-sql es un ORM.No afecta la forma en que diseña una aplicación de N niveles.Lo usas de la misma manera que usarías cualquier otro ORM.

@liammclennan

Que devolverá IEnumerable....Linq-to-sql es un ORM.No afecta la forma en que diseña una aplicación de N niveles.Lo usas de la misma manera que usarías cualquier otro ORM.

Entonces supongo que todavía estoy confundido.Sí, Linq-to-Sql es un ORM;pero por lo que puedo decir, todavía estoy llenando mi código de interfaz con declaraciones de tipo SQL en línea (linq, no SQL....pero aun así siento que esto debería abstraerse del front-end).

Supongamos que incluyo la declaración LINQ que hemos estado usando como ejemplo en un método.Por lo que puedo decir, la única forma en que puedo devolverlo es de esta manera:

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

}

Desde mi código de interfaz haría algo como esto:

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

Por supuesto, esto devuelve un IEnumerable;pero no puedo usar esto como cualquier otro ORM como usted dice (a menos, por supuesto, que no entienda bien), porque no puedo hacer esto (nuevamente, este es un ejemplo artificial):

txtEmployeeName.Text = emps[0].FullName

Esto es lo que quise decir con "pierdo la bondad tipada fuerte". Creo que estoy empezando a estar de acuerdo con Crucible;que LINQ-to-SQL no fue diseñado para usarse de esta manera.De nuevo, si no veo las cosas correctamente, que alguien me muestre el camino :)

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top