2016-05-17 79 views
-1

我正在C#中使用VS2012创建一个Web应用程序来跟踪对客户的联系尝试。我正在保存联系尝试,有2个联系尝试类型的ref表和联系尝试结果,因为这些值始终是固定值。我遇到的问题是,当我从数据库中检索App_ContactAttempt时,它将带回没有附加的Ref_ContactOutcome和Ref_ContactType实体的App_ContactAttempt实体。我在上下文文件中启用了延迟加载并启用了代理创建,并且所有ref表属性都设置为虚拟。但是当我从数据库中获得App_ContactAttempt时,并没有附加ref表。任何人有任何想法我可以做什么?如果您需要更多信息,我可以提供。不能'EF6加载相关实体

UPDATE 好吧,我有一个服务的设置,以获得App_ContactAttempt,它看起来像这样:

public App_ContactAttempt GetContactAttempt(int contactAttemptId) 
    { 
     using (var logger = new MethodLogger(contactAttemptId)) 
     { 
      var contactAttempt = new App_ContactAttempt(); 
      try 
      { 
       contactAttempt = _unitOfWork.ContactAttempts.Get(contactAttemptId); 
      } 
      catch (Exception e) 
      { 
       logger.LogException(e.InnerException); 
      } 
      return contactAttempt; 
     } 
    } 

当我使用这个服务,我回来App_ContactAttempt当我打电话的服务,但Ref_ContactType和Ref_ContactOutcome为null。但是,当我使用DB背景下,像这样从控制器内打电话到DB:

var db = new ParsDatabaseContext(); 

    var contactAttemptTest1 = _clientService.GetContactAttempt(contactAttempt.ContactAttemptId); 

    var contactAttemptTest2 = db.App_ContactAttempt.Where(x => x.ContactAttemptId == contactAttempt.ContactAttemptId); 

的contactAttemptTest1返回与Ref_ContactType和Ref_ContactOutcome均为空的App_ContactAttempt。但是,contactAttemptTest2返回App_ContactAttempt,其中Ref_ContactType和Ref_ContactOutcome都被填充。希望这有助于缩小我的问题,因为我还没有线索..

更新2 这里有上下文和类,如果他们在所有帮助:

Context.cs

public partial class ParsDatabaseContext : DbContext 
{ 
    public ParsDatabaseContext() 
     : base("name=ParsDatabaseContext") 
    { 
     this.Configuration.LazyLoadingEnabled = true; 
     this.Configuration.ProxyCreationEnabled = true; 
    } 

    protected override void OnModelCreating(DbModelBuilder modelBuilder) 
    { 
     throw new UnintentionalCodeFirstException(); 
    } 

    public DbSet<App_Client> App_Client { get; set; } 
    public DbSet<App_ContactAttempt> App_ContactAttempt { get; set; } 
    public DbSet<Ref_ContactOutcome> Ref_ContactOutcome { get; set; } 
    public DbSet<Ref_ContactType> Ref_ContactType { get; set; } 

    public virtual ObjectResult<GetClient_Result> GetClient(Nullable<int> clientID) 
    { 
     var clientIDParameter = clientID.HasValue ? 
      new ObjectParameter("ClientID", clientID) : 
      new ObjectParameter("ClientID", typeof(int)); 

     return ((IObjectContextAdapter)this).ObjectContext.ExecuteFunction<GetClient_Result>("GetClient", clientIDParameter); 
    } 
} 

App_ContactAttempt.cs

public partial class App_ContactAttempt 
{ 
    public int ContactAttemptId { get; set; } 
    public int ClientId { get; set; } 
    public Nullable<System.DateTime> ContactDate { get; set; } 
    public Nullable<int> ContactType { get; set; } 
    public Nullable<int> ContactOutcome { get; set; } 
    public string Notes { get; set; } 

    public virtual Ref_ContactOutcome Ref_ContactOutcome { get; set; } 
    public virtual Ref_ContactType Ref_ContactType { get; set; } 
} 

Ref_ContactOutcome.cs

public partial class Ref_ContactOutcome 
{ 
    public Ref_ContactOutcome() 
    { 
     this.App_ContactAttempt = new HashSet<App_ContactAttempt>(); 
    } 

    public int ContactOutcomeId { get; set; } 
    public string Description { get; set; } 

    public virtual ICollection<App_ContactAttempt> App_ContactAttempt { get; set; } 
} 

Ref_ContactType.cs

public partial class Ref_ContactType 
{ 
    public Ref_ContactType() 
    { 
     this.App_ContactAttempt = new HashSet<App_ContactAttempt>(); 
    } 

    public int ContactTypeId { get; set; } 
    public string Description { get; set; } 

    public virtual ICollection<App_ContactAttempt> App_ContactAttempt { get; set; } 
} 
+0

'有没有附表' - 你是什么意思?在调试的时候,你看到属性'Ref_ContactOutcome',它是空的或什么? –

+0

您必须在存储库模式中使用'Include'扩展名或启用延迟加载。 – Igor

+1

对于延迟加载的工作,在您访问导航属性时,您从*加载实体的上下文*必须可用(并且未处理)。如果您想使用非常短暂的上下文,请使用预先加载(例如'Include') – Jcl

回答

2

问题是只有在用于创建代理类的DBContext可用时,延迟加载才有效。在你的情况是代理分离,因为用于打包App_ContactAttempt类型的代理对象contactAttempt的DBContext已经被处置。

还要确保:

dbContext.Configuration.ProxyCreationEnabled = true; 

而且你可以检查,如果对象是代理

public static bool IsProxy(object type) 
{ 
    return type != null && ObjectContext.GetObjectType(type.GetType()) != type.GetType(); 
} 

https://msdn.microsoft.com/en-us/library/ee835846%28v=vs.100%29.aspx

this answer检查,如果您的代理实体连接到的DbContext 。

您可以将现有的分离实体到另一个现有的情况下,使其再次延迟加载:

db.App_ContactAttempts.Attach(contactAttemptTest1); 

如果你有,你知道已经存在于数据库中,但 的实体,目前不被上下文跟踪,那么你可以告诉 上下文来使用DbSet上的Attach方法跟踪实体。上下文中的 实体将处于未更改状态。

请参阅here

所以在你的例子:

using (var db = new ParsDatabaseContext()) 
{ 
    var contactAttemptTest1 = _clientService.GetContactAttempt(contactAttempt.ContactAttemptId);  
    db.App_ContactAttempts.Attach(contactAttemptTest1);  
    Debug.Print(contactAttemptTest1.Ref_ContactType.Description); 
} 

应该工作。

0

使用包括。

例如:

var contactAttemps = db.App_ContactAttempts 
         .Includes("Ref_ContactOutcome") 
         .Includes("Ref_ContactTypes") 
         .ToList(); 
+0

我使用存储库模式从数据库中获取实体我有一个服务设置,我通过ContactAttemptId,这使我回到该记录,但Ref_ContactOutcome和Ref_ContactTypes都为null。 – necrofish666

-1

要退实体本身或DTO(数据传输对象)?

如果您要返回DTO,请确保映射已正确完成。

发布您的实体对象。

相关问题