Click here to Skip to main content
15,890,527 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
I've created a definition for the UserProfile table that the web authentication stuff uses:

	[Table("UserProfile")]
public class UserProfile
{
  [Key]
  [DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
  public int UserId { get; set; }
  public string UserName { get; set; }
}


Now, I reference it in a supplementary table (probably not the best implementation, I should just add the fields I want to the UserProfile table, but I wanted to leave UserProfile "pure"):

[Table("UserInfo")]
public class UserInfo
{
[Key]
[DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }

[Required]
public int UserId { get; set; } // FK to UserProfile.UserId

[ForeignKey("UserId")]
public UserProfile UserProfile { get; set; }

... other stuff ....


And yes, the table name should probably have been pluralized, but "UserInfos" is sort of lame. Anyways, I do this:

var context = new UsersContext();
var userInfo = context.UserInfo;

foreach (UserInfo ui in userInfo) {...stuff...}


and for some ridiculous reason, ui.UserProfile is null.

Now, I read up on lazy loading, using "virtual" (which seems related to collections instead), tried setting the flag to false in the Context definition, nothing works.

So: workaround:

foreach (UserInfo ui in userInfo) 
{
  UserProfile up = context.UserProfiles.Find(ui.UserId);
  ... stuff ...
}


and I get an exception that a context is already open!!!

So, workaround 2, create a second context.

Wow, really? Is EF that lame?

How do I get it to load the UserProfile property?

Does it not know how to do a join?

Is it failing to do this because I haven't defined it as a collection?

Is there some way I have to tell EF that this is a 1:1 relationship so I don't need a collection?
Posted

1 solution

Sir,
Since, you are using one to one relationship, then there is no need to have ICollection of the other entity.
The exceptions occur because the connections are present in a connection pool, so when we use the context to connect to database table a connection is pulled and used. So the connection needs to be disposed after being used, here disposed actually means, itreturns back to the pool.
C#
 using(var testContext = new ContextName)
{
    //Your query goes here...
}

With the use of using(), the dbContext object gets disposed after use.
For the query you have stated,
the query can be written as:-
C#
var userProfiles = context.UserInfo.Include( s => s.UserProfiles).Where(Condition goes here);

The structure should be like:-
C#
[Table("UserInfo")]
public class UserInfo
{
[Key]
[DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }

[Required]
[Key, ForeignKey("UserProfile")]
public int UserId { get; set; } // FK to UserProfile.UserId

public UserProfile UserProfiles { get; set; }

I hope the DBContext would be like as below:-
C#
public class UserContext : DbContext
{
    public DbSet<UserInfo> UserInfos { get; set; }
    public DbSet<UserProfile> UserProfiles { get; set; }
}

Sir,
It is advisable to avoid using many context for many queries. We can avoid that using Dependency Injection or the using()statement and inside that one context instantiated is used. So, the same context should be used disposing after the use.
Override Method Dispose is also used, by inheriting the repository from IDisposible
C#
public void Dispose()
{
     db.Dispose();
}

Hope I managed to convey atleast something Sir.
Thanks.
:)
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900