2009-09-02 9 views
6

Tengo un modelo sobre mi modelo de base de datos y mapeo los objetos en mi Repositorio.¿Cómo usar las clases de fábrica con linq para sql?

Sin embargo, aparentemente hace una diferencia si "selecciono nuevo" directamente en mis GetUsers o "selecciono factoryresult" como se implementa a continuación. Aparece el error en tiempo de ejecución, que el método CreateFromDbModel no tiene una traducción a sql (System.NotSupportedException).

¿Hay alguna forma de evitar esto? ¿Puedo repararlo de alguna manera?

La razón para querer utilizar el método de fábrica es que pueda instanciar objetos en otro lugar y quiere mantener el 'código de correspondencia' en un solo lugar ...

Gracias por cualquier comentario, Anders

public IQueryable<User> GetUsers(bool includeTeams) 
    { 
     return from u in _db.sc_Players 
       where (includeTeams || (!u.aspnet_User.sc_Player.IsTeam)) 
       select UserFactory2.CreateFromDbModel(u); 
    } 


    public static User CreateFromDbModel(sc_Player player) 
    { 
     return new User 
        { 
         Id = player.sc_PlayerID, 
         FirstName = player.FirstName.Trim(), 
         LastName = player.LastName.Trim(), 
         PresentationName = player.FirstName.Trim() + " " + player.LastName.Trim(), 
         LoginName = player.aspnet_User.LoweredUserName, 
         IsTeam = player.IsTeam, 
         Email = player.aspnet_User.aspnet_Membership.Email, 
         Password = player.aspnet_User.aspnet_Membership.Password 
        }; 
    } 

Respuesta

1

¿El problema es que está devolviendo IQueryable en su método GetUsers? Intenta devolver List en su lugar. Esto obligará a la consulta de Linq a ejecutarse dentro del método.

public List<User> GetUsers(bool includeTeams) 
{ 
    return (from u in _db.sc_Players 
    where (includeTeams || (!u.aspnet_User.sc_Player.IsTeam)) 
    select UserFactory2.CreateFromDbModel(u)).ToList(); 
} 

No estoy seguro si esto va a solucionar el problema, sólo una corazonada. Pude duplicar lo que estás haciendo en Linqpad en una base de datos local, y funcionó. Pero mi muestra no devolvía un IQueryable. ¿Estás modificando la colección de IQueryable fuera de GetUsers()?

Editar:

he hecho un poco más de cheques. Yo era capaz de duplicar el error sólo cuando lo modifico mi muestra por lo que la colección IQueryable se utilizó en una segunda consulta LINQ después de llamar GetUsers():

IQueryable<User> query = GetUsers(true); 

var q = from u in query 
    where u.Name.Contains("Bob") 
    select new {Name = u.FirstName + " " + u.LastName}; 

apuesto si va a devolver una lista como se sugirió anteriormente en GetUsers() el error desaparecerá. El único inconveniente es que cualquier filtrado que realice después de llamar a GetUsers() no limitará la cantidad de datos devueltos desde la base de datos porque ya ha ejecutado la consulta al llamar a .ToList().

Edición 2:

Por desgracia, no creo que haya otra manera de incluir su método de fábrica en la consulta. Tengo una idea más. Puede crear un método de extensión para IQueryable, llámelo algo así como ToUserList(). Dentro de ToUserList() llama a ToList() en la consulta y su método de fábrica que devuelve una colección de usuarios. Llame a este método cuando termine de filtrar los datos usando Linq. Esto le permitirá ejecutar solo la consulta cuando esté listo para cargar los datos de la base de datos. Un ejemplo se da a continuación.

public static List<Users> ToUserList(this IQueryable<User> query) 
{ 
    return query.ToList().Select(u => UserFactory2.CreateFromDbModel(u)); 
} 

llamada el método de extensión de esta manera:

// Filter the data using linq. When you are ready to execute the query call: 
query.ToUserList(); // Query will execute and a list of User objects returned. 

la esperanza que esto tiene sentido. Douglas H.

+0

Gracias Douglas y Rossisdead, me han tratado de convertir a la lista antes de llamar a mi método de fábrica, pero no sólo tengo que devolver todo el LINQ objetos de la base de datos, que tienen que construir toda mi modelo de objetos de dominio, así - y yo estaba tratando de encontrar una manera que no requiere que ... Además, me hacen filtrando en mi capa de servicio y tendrá que convertir la lista de nuevo a consultable ... –

+0

Hola Anders, Ver Editar 2 anterior. – Douglas

+0

Hola Douglas, que marque su respuesta como la respuesta, pero yo tenía la esperanza de mantener los objetos LINQ base de datos en la capa de datos donde su sugerencia sería exponer los objetos de la capa de datos a la capa de servicio. –

1

El error lo explica todo.

"método CreateFromDbModel no tiene una traducción a sql (Sistema.NotSupportedException)"

Su método CreateFromDbModel no es una función de SQL. Su aplicación no será capaz de ejecutar la función CreateFromDbModel hasta que los objetos se devuelven específicamente para usted desde el servidor. Lo más probable es que llamar a una ToList() o algo similar en su consulta antes de poder ejecutar CreateFromDbModel en ellos.

Cuestiones relacionadas