views:

1459

answers:

3

I have a following SQL Server 2005 database schema:

CREATE TABLE Messages (
   MessageID int,
   Subject varchar(500),
   Text varchar(max) NULL,
   UserID NULL
)

The column "UserID" - which can be null - is a foreign key and links to the table

CREATE TABLE Users (
   UserID int,
   ...
)

Now I have several POCO classes with names Message, User etc. that I use in the following query:

public IList<Message> GetMessages(...) {
  var q = (from m in dataContext.Messages.Include("User")
           where ...
           select m); // could call ToList(), but...

  return (from m in q
          select new Message {
            ID = m.MessageID,
            User = new User {
              ID = m.User.UserID,
              FirstName = m.User.FirstName,
              ...
            }
          }).ToList();
}

Now note that I advise the entity framework - using Include("Users") - to load a user associated with a message, if any. Also note that I don't call ToList() after the first LINQ statement. By doing so only specified columns in the projection list - in this case MessageID, UserID, FirstName - will be returned from the database.

Here lies the problem - as soon as Entity Framework encounters a message with UserID == NULL, it throws an exception, saying that it could not convert to Int32 because the DB value is NULL.

If I change the last couple of lines to

return (from m in q
        select new Message {
           ID = m.MessageID,
           User = m.User == null ? null : new User {
              ID = m.User.UserID,
              ...
           }
        }).ToList()

then a run-time NotSupportedException is thrown telling that it can't create a constant User type and only primitives like int, string, guid are supported.

Anybody has any idea how to handle it besides materializing the results just right after the first statement and using in-memory projection afterwards? Thanks.

A: 

I suspect your relationship is not 1 to 1.

leppie
Right, this is 1:n relationship, a message belongs to only 1 user, but a user can have several messages.
What does the m.Users property do? I assumed that was a bunch of User associated with the Message.
leppie
OK, m.Users should actually be m.User, I've changed it in the original question. This propery is an entity pointing to the user that submitted this message.
A: 

Since you did an .Include("Users") you should be able to just traverse the User property in the Message object to get the information your want.

Orion Adrian
Yes, this is the way I do it, except when there is no user associated with the message (remember, UserID is nullable).
If there's no user object, then you'd want a null value. What are you looking for instead?
Orion Adrian
+2  A: 

You forgot to include the declaration of your "Message" class but I suspect that the UserID property in that class is not declared as a nullable type. If that is the case, change it from "int" to "int?" (nullable int).

KristoferA - Huagati.com
I think that this discussion on the MS forums also applies. It probably does the same thing as what this answer suggests.http://social.msdn.microsoft.com/forums/en-US/adodotnetentityframework/thread/d206f59c-2ccc-4c93-917d-0bcbd40dfa1b/
villecoder