我是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; }
}
使用控制器:
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);
}
}
最近我有一个要显示新数据的新表
CREATE TABLE customerDetails
(
CustomerNumber int,
Role nvarchar(20),
ContactName nvarchar(30)
)
对于每个客户编号,customerDetails表中有2个条目,每个角色的角色各不相同,例如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; }
}
并修改了控制器:
[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;
}
但是它返回一个空集。如何在此处正确编写该select语句并填充修改后的Customer
实体?
答案 0 :(得分:1)
您的实体应反映您的总体表结构。给定一个具有CustomerDetails实体的Customer实体,并且在CustomerNumber上两者之间存在1-many关系,则我将这些实体定位为:
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;}
}
...并映射客户和客户详细信息。请注意,CustomerDetails将拥有自己的PK列,而不是CustomerNumber,因为对于单个客户,您可能拥有2倍的客户详细信息(角色A和角色B)
我建议不要将实体传递到您的视图,而应创建视图模型供视图使用,并使用.Select
从您的实体中选择相关详细信息。这是最佳性能,它允许您格式化/展平数据以适合您的视图,并且比将整个实体图暴露给使用者更安全。
或者,如果您希望为客户使用一组特定的相关角色(可选),则customer表中的RoleACustomerDetailsId和RoleBCustomerDetailsId为int?
,然后可以引用这些相关实体。