实体框架实际上是这个跛脚(解析1:1外键对象) [英] Is the Entity Framework actually this lame (resolving 1:1 Foreign Key objects)

查看:37
本文介绍了实体框架实际上是这个跛脚(解析1:1外键对象)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经为Web身份验证资料使用的UserProfile表创建了一个定义:



 [表(UserProfile)] 
public class UserProfile
{
[Key]
[DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
public int UserId {get;组; }
公共字符串UserName {get;组; }
}





现在,我在一个补充表中引用它(可能不是最好的实现,我应该添加字段我想要UserProfile表,但我想让UserProfile纯粹):



 [表(UserInfo)] 
公共类UserInfo
{
[Key]
[DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
public int Id {get;组; }

[必需]
public int UserId {get;组; } // FK到UserProfile.UserId

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

......其他东西....





是的,表名可能应该有已经多元化,但UserInfos有点蹩脚。无论如何,我这样做:



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

foreach(userInfo中的UserInfo ui){... stuff ...}





和某些人荒谬的原因,ui.UserProfile是null。



现在,我读到延迟加载,使用虚拟(这似乎与集合相关),尝试设置在上下文定义中标记为false,没有任何作用。



所以:解决方法:



 foreach(userInfo中的UserInfo ui)
{
UserProfile up = context.UserProfiles.Find(ui.UserId);
......东西...
}





我得到一个异常,即上下文已经打开!!!



因此,解决方法2,创建第二个上下文



哇,真的吗? EF是蹩脚的吗?



如何让它加载UserProfile属性?



不知道如何加入?



是否未能这样做,因为我没有将其定义为集合?



有什么方法我必须告诉EF这是一个1:1的关系所以我不需要一个集合吗?

解决方案

先生,

既然你正在使用一对一的关系,那么就没有必要对另一个实体进行ICollection。

由于连接存在于连接池中,因此发生异常,因此当我们使用上下文连接到数据库表时,将拉取并使用连接。因此连接需要在使用后进行处理,这里配置实际意味着,它返回到池中。

 使用 var  testContext = < span class =code-keyword> new  ContextName)
{
// 您的查询在这里...
}



使用using(),dbContext对象在使用后被释放。 />
对于您所说的查询,

查询可以写成: -

  var  userProfiles = context.UserInfo.Include(s = >  s.UserProfiles)。Where(条件在这里); 



结构应如下: -

 [表(   UserInfo)] 
public class UserInfo
{
[Key]
[DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
< span class =code-keyword> public int ID { get ; set ; }

[必需]
[Key,ForeignKey( UserProfile)]
public int UserId {获得; set ; } // FK to UserProfile.UserId

public UserProfile UserProfiles { get ; set ; }



我希望DBContext如下所示: -

  public   class  UserContext:DbContext 
{
public DbSet<&的UserInfo GT; UserInfos { get ; set ; }
public DbSet< UserProfile> UserProfiles { get ; set ; }
}



先生,

建议避免在许多查询中使用许多上下文。我们可以避免使用依赖注入或using()语句,并在内部使用实例化的一个上下文。因此,在使用后应使用相同的上下文。

通过从IDisposible继承存储库来使用覆盖方法Dispose

  public   void  Dispose()
{
db.Dispose();
}



希望我设法传达至少一些先生。

谢谢。

:)


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?

解决方案

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.

 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:-

var userProfiles = context.UserInfo.Include( s => s.UserProfiles).Where(Condition goes here);


The structure should be like:-

[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:-

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

public void Dispose()
{
     db.Dispose();
}


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


这篇关于实体框架实际上是这个跛脚(解析1:1外键对象)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆