C# 选择“将结果联接到结果”时出现问题

C# 选择“将结果联接到结果”时出现问题,c#,entity-framework,C#,Entity Framework,我是EF的新手。为了简单起见,比如说直到最近,我有一张这样的桌子 CREATE TABLE customer ( CustomerNumber int, CustomerName nvarchar(100) ) 我有一门课来处理这件事 [Table("customer")] public class Customer { [Key] public int CustomerNumber { get; set; } public string Custome

我是EF的新手。为了简单起见,比如说直到最近,我有一张这样的桌子

CREATE TABLE customer
(
    CustomerNumber int,
    CustomerName nvarchar(100)
)
我有一门课来处理这件事

[Table("customer")]
public class Customer
{
    [Key]
    public int CustomerNumber { get; set; }
    public string CustomerName { get; set; }
}
结合上下文:

public class MyContext : DbContext
    {
        public MyContext()
                : base("name=MyContext")
        {
        }

        public DbSet<Customer> Customers { get; set; }

    }
对于每个客户编号,customerDetails表中有两个条目,角色不同,比如
A
B

我想做的是将下面查询的结果放入我修改过的实体中

查询:

SELECT c.CustomerNumber, c.CustomerName, cc1.ContactName as A_Name, cc2.ContactName as B_Name
FROM customer as c
JOIN customerDetails as cc1 ON c.CustomerNumber = cc1.CustomerNumber AND cc1.Role = 'A'
JOIN customerDetails as cc2 ON c.CustomerNumber = cc2.CustomerNumber AND cc2.Role = 'B'
我修改了我的实体:

[Table("customer")]
public class Customer
{
    [Key]
    public int CustomerNumber { get; set; }
    public string CustomerName { get; set; }
    public string A_Name { get; set; }
    public string B_Name { get; set; }
}
增加:

[Table("customerDetails")]
public class Customer
{
    [Key]
    public int CustomerNumber { get; set; }
    public string Role { get; set; }
    public string ContactName { get; set; }
}
并修改了控制器:

public class CustomersController : ODataController
    {
        MyContext db = new MyContext();

        private bool CustomerExists(string key)
        {
            return db.Customers.Any(p => p.CustomerNumber == key);
        }

        protected override void Dispose(bool disposing)
        {
            db.Dispose();
            base.Dispose(disposing);
        }

        [EnableQuery(PageSize =20)]
        public IQueryable<Customer> Get()
        {
            db.Database.ExecuteSqlCommand("SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;");
            return db.Customers;
        }

        [EnableQuery]
        public SingleResult<Customer> Get([FromODataUri] string key)
        {
            IQueryable<Customer> result = db.Customers.Where(p => p.CustomerNumber == key);
            return SingleResult.Create(result);
        }

    }
[EnableQuery(PageSize =20)]
        public IQueryable<Customer> Get()
        {
            db.Database.ExecuteSqlCommand("SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;");
            return from c in db.Customers
                   join cc1 in db.CustomerContacts.Where(e => e.Role == "A") on c.CustomerNumber equals cc1.CustomerNumber
                   join cc2 in db.CustomerContacts.Where(e => e.Role == "B") on c.CustomerNumber equals cc2.CustomerNumber
                   select c;
        }
[启用查询(PageSize=20)]
公共IQueryable Get()
{
db.Database.ExecuteSqlCommand(“设置事务隔离级别读取未提交;”);
以数据库形式从c返回。客户
在db.CustomerContacts中加入cc1,其中c.CustomerNumber上的(e=>e.Role==“A”)等于cc1.CustomerNumber
在db.CustomerContacts中加入cc2,其中c.CustomerNumber上的(e=>e.Role==“B”)等于cc2.CustomerNumber
选择c;
}

但它返回一个空集。如何在此处正确编写select语句并填充修改后的
Customer
实体?

您的实体应反映您的整体表结构。给定一个具有CustomerDetails实体的客户实体,以及CustomerNumber上这两个实体之间的一对多关系,我会将这些实体定位为:

public class Customer
{
   public int CustomerNumber {get; set;}
   public virtual ICollection<CustomerDetails> CustomerDetails {get; set;}
}

public class CustomerDetails
{
   public int CustomerDetailId {get; set;}
   public string Role {get; set;}
   public int CustomerNumber {get; set;}
}
公共类客户
{
public int CustomerNumber{get;set;}
公共虚拟ICollection客户详细信息{get;set;}
}
公共类客户详细信息
{
public int CustomerDetailId{get;set;}
公共字符串角色{get;set;}
public int CustomerNumber{get;set;}
}
。。。并映射客户和客户详细信息。注意CustomerDetails将有它自己的PK列,而不是CustomerNumber,因为对于单个客户,您可能有2倍的客户详细信息(角色a和角色B)

我建议不要将实体传递给视图,而是创建视图模型供视图使用,并使用
从实体中选择相关细节。选择
。这对性能来说是最好的,允许您格式化/展平数据以适合您的视图,并且比向消费者公开整个实体图更安全

或者,如果您希望为客户指定一组特定的相关角色(可选),则客户表应具有RoleCustomerDetailSID和RoleBCusterDetailSID作为
int?
,然后可以引用这些相关实体

public class Customer
{
   public int CustomerNumber {get; set;}
   public virtual ICollection<CustomerDetails> CustomerDetails {get; set;}
}

public class CustomerDetails
{
   public int CustomerDetailId {get; set;}
   public string Role {get; set;}
   public int CustomerNumber {get; set;}
}