2009-03-16 17 views
7

En la base de datos, tengo una tabla llamada Contacto. El primer nombre y otros campos de cadena están diseñados para usar un tipo de datos Char (no el diseño de mi base de datos). Mi contacto de contacto se asigna a un tipo de cadena en las propiedades. Si lo que quería hacer una prueba sencilla de recuperar un objeto de contacto por id, me gustaría hacer algo como esto:Cómo recortar los valores usando Linq a Sql?

Contact contact = db.Contacts.Single(c => c.Id == myId); 
Contact test = new Contact(); 
test.FirstName = "Martin"; 

Assert.AreEqual(test.FirstName, contact.FirstName); 

El valor contact.FirstName es "Martin" debido al tipo char. ¿Dónde puedo interceptar la propiedad FirstName cuando se está cargando? OnFirstNameChanging (valor de cadena) no se invoca en la carga inicial (contacto), pero lo hace en el objeto de prueba.

Respuesta

8

¿Quizás podría ponerlo en el método parcial OnLoaded()? Nota: Nunca he usado esto, pero supongo que se vería así:

public partial class Contact 
{ 
    partial void OnLoaded() 
    { 
     FirstName = FirstName.Trim(); 
    } 
} 
+0

Esto funciona. Es bastante fácil de hacer para cada campo porque no estoy mostrando tantos campos para mostrar. Gracias. – Marsharks

+0

Esto generará un evento de cambio de propiedad, que podría desencadenar otras acciones, y podría generar actualizaciones innecesarias en la base de datos, ya que está cambiando el valor de la propiedad sin realizar ningún cambio semántico en el contenido. – tvanfosson

+3

El objetivo de la pregunta era encontrar el lugar para hacer tal lógica (en este caso OnLoaded()); El método en sí mismo podría consistir fácilmente en "_FirstName = _FirstName.Trim();" para evitar el apropiado cambio de disparo del evento. –

1
Contact contact = db.Contacts.Single(c => c.Id.Trim() == myId); 

Y compruebe que el proveedor LINQ traduce eso en el SQL apropiado.

+0

No creo que el problema haya sido con el campo Id. – tvanfosson

+1

@tvanfosson - Creo que el op quiso solo por ejemplos, no debe tomarse literalmente. –

6

Si no puede cambiar el esquema, es posible que desee hacer que el acceso de acceso creado por el diseñador sea privado/protegido y cree un acceso público para front-end de la propiedad en una implementación de clase parcial. Luego puede Recortar el valor en el acceso de obtención.

public partial class Contact 
{ 

    public string RealFirstName 
    { 
     get { return this.FirstName.Trim(); } 
     set { this.FirstName = value; } 
    } 

    ... 
} 
+1

Esta es una buena solución, porque no solo los campos son de tipo char, también se llaman First_Name. Así que podría arreglar todos los campos también, sin cambiarlo en mi diseñador de Objetos. – Marsharks

+0

El problema es cuando creo una consulta y trato de usar algo como FullName = c.FirstName + '' + c.LastName. Estaba obteniendo la expresión No se pudo traducir y no pude tratarlo como un mensaje de expresión local. – Marsharks

+0

Una vez que haya realizado su filtrado, puede usar ToList() para generar la consulta real y luego hacer su selección en la lista resultante. Como son objetos en ese punto, la construcción de FullName debería funcionar. – tvanfosson

0

Se puede ejecutar un ForEach en su lista de contactos antes de intentar buscar Martin.

var contacts = db.Contacts.ForEach(c => c.FirstName = c.FirstName.Trim()); 
Contact contact = contacts.Single(c => c.Id == myId); 
contact.FirstName // = "Martin" 

Pero esto no es muy fácil de mantener si se tiene que hacer para varios campos.

+0

¿Qué sucede si tiene 100.000 contactos? –

1

Depende del control que tenga sobre el esquema y el código.

Si los valores se configuran llamando a un constructor con todos los parámetros, haga los ajustes, etc., ya que están asignados a las variables miembro.

Si se asignan a las propiedades (probablemente del ejemplo), cambie el acceso SET para que haga el recorte allí.

Tiene problemas potenciales si realmente QUIERE espacios iniciales o finales en algún momento.

Si no puede modificar el código de la clase base, intente utilizar clases parciales, o heredar de la clase y anular las propiedades allí.

Si no puede hacer eso, mi última sugerencia sería escribir una clase de fábrica de algún tipo que pase un objeto creado y lo limpie según las reglas que desee.