Entity framework 4 使用实体框架和SQL查询建立外键连接

Entity framework 4 使用实体框架和SQL查询建立外键连接,entity-framework-4,Entity Framework 4,我有几个类(无论如何在本例中)首先使用实体框架中的代码连接到数据库 public class Customer { [Key] public long CustomerId { get; set; } public string CompanyName { get; set; } ... public virtual List<Contact> Contacts { get; set; } } public class Contact {

我有几个类(无论如何在本例中)首先使用实体框架中的代码连接到数据库

public class Customer
{
    [Key]
    public long CustomerId { get; set; }
    public string CompanyName { get; set; }
    ...
    public virtual List<Contact> Contacts { get; set; }
}

public class Contact
{
    [Key]
    public long ContactId { get; set; }
    public string Forename { get; set; }
    ...
    public long CustomerId { get; set; }

    public virtual Customer Customer { get; set; }
}
公共类客户
{
[关键]
公共长CustomerId{get;set;}
公共字符串CompanyName{get;set;}
...
公共虚拟列表联系人{get;set;}
}
公共类联系人
{
[关键]
公共长联系人ID{get;set;}
公共字符串名{get;set;}
...
公共长CustomerId{get;set;}
公共虚拟客户客户{get;set;}
}
当我在上下文类中将这些直接连接到db时,外键关系连接良好,我可以从customer类中访问联系人集合

class RemoteServerContext : DbContext 
{
    public DbSet<Customer> Customers { get; set; }
    public DbSet<Contact> Contacts { get; set; }
    ...
}
类RemoteServerContext:DbContext
{
公共数据库集客户{get;set;}
公共数据库集联系人{get;set;}
...
}
我的问题是,这些数据库表被各种不同的系统使用,而且数量庞大。为了提高效率,我已经覆盖了默认行为,以指向一个视图(以及其他地方的存储过程),而不是直接指向表

    public IEnumerable<Customer> Customers ()
    {
        return Database.SqlQuery<Customer>("SELECT * FROM vw_CustomerList");
    }

    public IEnumerable<Contact> Contacts()
    {
        return Database.SqlQuery<Contact>("SELECT * FROM vw_ContactsList");
    }
公共IEnumerable客户()
{
return Database.SqlQuery(“从vw_CustomerList中选择*);
}
公共IEnumerable联系人()
{
return Database.SqlQuery(“从vw_联系人列表中选择*);
}
我确保在每个视图中都包含外键字段:CustomerId和ContactId

然而,当我这样做时,类连接似乎丢失了——当我钻取其中一个应该指向另一个对象的对象时,总会有一个null。我已经尝试设置外键字段应该指向什么,但这似乎也没有帮助

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Contact>().HasRequired(p => p.Customer)
            .WithMany()
            .HasForeignKey(k => k.CustomerId);
    }
模型创建时受保护的覆盖无效(DbModelBuilder modelBuilder)
{
modelBuilder.Entity().HasRequired(p=>p.Customer)
.有很多
.HasForeignKey(k=>k.CustomerId);
}

在覆盖默认行为时,是否有方法建立连接?

在这种情况下没有覆盖。如果你移除

public DbSet<Customer> Customers { get; set; }
完成此操作后,您可以使用以下方法重试:

public DbSet<Customer> Customers { get; set; }
公共数据库集客户{get;set;}
除非您的视图是可更新的,否则每次尝试添加、更新或删除此集合中的任何客户时都会出现异常。在映射到视图的
客户
联系人
之间的关系之后,您的导航属性应该能够正常工作


SqlQuery的问题在于它的工作方式。它返回分离的实体。分离的实体未连接到上下文,并且不会延迟加载其导航属性。您必须手动将每个客户实例附加回上下文,要执行此操作,您再次需要
DbSet

在这种情况下没有覆盖。如果你移除

public DbSet<Customer> Customers { get; set; }
完成此操作后,您可以使用以下方法重试:

public DbSet<Customer> Customers { get; set; }
公共数据库集客户{get;set;}
除非您的视图是可更新的,否则每次尝试添加、更新或删除此集合中的任何客户时都会出现异常。在映射到视图的
客户
联系人
之间的关系之后,您的导航属性应该能够正常工作


SqlQuery的问题在于它的工作方式。它返回分离的实体。分离的实体未连接到上下文,并且不会延迟加载其导航属性。您必须手动将每个客户实例连接回上下文,要做到这一点,您需要再次使用
DbSet

您好,这很好。非常感谢。我希望用我被告知要使用的一组现有存储过程覆盖事务性内容:创建、编辑、删除。感谢您的帮助如果要覆盖存储过程的创建、编辑和删除操作,则不能先使用代码,因为它不支持存储过程映射。你需要使用EDMX。你刚刚让我在几周内遇到了一个大问题,而且比我目前所做的还要多。非常感谢。切换到EDMXHi,太好了。非常感谢。我希望用我被告知要使用的一组现有存储过程覆盖事务性内容:创建、编辑、删除。感谢您的帮助如果要覆盖存储过程的创建、编辑和删除操作,则不能先使用代码,因为它不支持存储过程映射。你需要使用EDMX。你刚刚让我在几周内遇到了一个大问题,而且比我目前所做的还要多。非常感谢。切换到EDMX