广东话'获取EF6加载相关实体

时间:2016-05-17 10:49:36

标签: c# asp.net-mvc entity-framework visual-studio

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

更新 是的,我有一个服务设置来获取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返回App_ContactAttempt,其中Ref_ContactType和Ref_ContactOutcome都为null。但是,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; }
}

3 个答案:

答案 0 :(得分:2)

问题是只有在用于创建代理类的DBContext可用时,延迟加载才有效。在您的情况下,代理已分离,因为用于创建类型contactAttempt的代理对象App_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方法跟踪实体的上下文。该   实体将在上下文中处于Unchanged状态。

请参阅here

所以在你的例子中:

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

应该有用。

答案 1 :(得分:0)

使用包含。

例如:

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

答案 2 :(得分:-1)

您是返回实体本身还是DTO(数据传输对象)?

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

发布您的实体对象。