![](/img/trans.png)
[英]Problems with Data modeling and / or Querying a TPT model in Entity Framework
[英]Modeling nested data structures in Entity Framework
我正在尝试Entity Framework 7 RC1(每个主要版本,我都会检查一下是否值得解决),但是在尝试理解如何建模某些实体时遇到了一些麻烦。
作为示例,我回到了一个简单的真实应用程序中。 它用于管理Windows打印服务器(ugh)。
这是一些数据库表的示例:
这是DDL:
CREATE TABLE dbo.PrintServer
(
ID INT IDENTITY NOT NULL,
Name VARCHAR(MAX) NOT NULL,
Description VARCHAR(MAX) NULL,
CONSTRAINT [PK_PrintServer_ID] PRIMARY KEY (ID),
)
CREATE TABLE dbo.PrintServerSupport
(
ID INT IDENTITY NOT NULL,
ServerID INT NOT NULL,
TypeID INT NOT NULL,
ManufacturerID INT NOT NULL,
CONSTRAINT [PK_PrintServerSupport_ID] PRIMARY KEY (ID),
CONSTRAINT [FK_PrintServerSupport_ServerID] FOREIGN KEY (ServerID) REFERENCES PrintServer (ID) ON DELETE CASCADE,
CONSTRAINT [FK_PrintServerSupport_TypeID] FOREIGN KEY (TypeID) REFERENCES PrinterType (ID) ON DELETE CASCADE,
CONSTRAINT [FK_PrintServerSupport_ManufacturerID] FOREIGN KEY (ManufacturerID) REFERENCES PrinterManufacturer (ID) ON DELETE CASCADE
)
CREATE TABLE dbo.PrinterType
(
ID INT IDENTITY NOT NULL,
Type VARCHAR(MAX) NOT NULL,
CONSTRAINT [PK_PrinterType_ID] PRIMARY KEY (ID),
)
CREATE TABLE dbo.PrinterManufacturer
(
ID INT IDENTITY NOT NULL,
Manufacturer VARCHAR(MAX) NOT NULL,
CONSTRAINT [PK_PrinterManufacturer_ID] PRIMARY KEY (ID)
)
现在,将其转换为C#POCO实体显然符合以下几条原则:
public partial class PrinterManufacturer
{
public PrinterManufacturer()
{
PrintServerSupport = new HashSet<PrintServerSupport>();
}
public int ID { get; set; }
public string Manufacturer { get; set; }
public virtual ICollection<PrintServerSupport> PrintServerSupport { get; set; }
}
public partial class PrinterType
{
public PrinterType()
{
PrintServerSupport = new HashSet<PrintServerSupport>();
}
public int ID { get; set; }
public string Type { get; set; }
public virtual ICollection<PrintServerSupport> PrintServerSupport { get; set; }
}
public partial class PrintServer
{
public PrintServer()
{
PrintServerSupport = new HashSet<PrintServerSupport>();
}
public int ID { get; set; }
public string Description { get; set; }
public string Name { get; set; }
public virtual ICollection<PrintServerSupport> PrintServerSupport { get; set; }
}
public partial class PrintServerSupport
{
public int ID { get; set; }
public int ManufacturerID { get; set; }
public int ServerID { get; set; }
public int TypeID { get; set; }
public virtual PrinterManufacturer Manufacturer { get; set; }
public virtual PrintServer Server { get; set; }
public virtual PrinterType Type { get; set; }
}
现在,图像我想选择所有打印服务器,我只需要执行以下操作? (请记住,我在EF方面的EF经验非常有限)
using (var db = new DbContext())
{
var query = db.PrintServer.Include(s => s.PrintServerSupport);
}
但是,在调试时,这将返回以下相当奇怪的结果集:
如您所见,“制造商”和“类型”字段未填充。 奇怪的是,嵌套的服务器字段是...
为了使事情更加烦人,我还收到了带有嵌套数据的JSON有效负载。 这是一个例子:
[
{
"Name":"REDACTED",
"Description":"Xerox MFP TEST",
"SupportedPrinters": [
{
"Type":"Printer",
"Manufacturer":"XEROX"
},
{
"Type":"Plotter",
"Manufacturer":"XEROX"
},
{
"Type":"MFP",
"Manufacturer":"XEROX"
}
]
},
{
"Name":"REDACTED-2",
"Description":"Xerox MFP TEST 2",
"SupportedPrinters": [
{
"Type":"Printer",
"Manufacturer":"SAMSUNG"
},
{
"Type":"Plotter",
"Manufacturer":"SAMSUNG"
}
]
}
]
对数据进行封送和拆封是一件容易的事,但是对数据进行封送再更新数据库又如何呢? 我总是发现这是一个非常困难的问题,并且我对EF应该如何在这里提供帮助感到好奇。
数据建模和查询的正确方法是什么?
我不认为在将导航属性标记为virtual
(例如在EF6中)默认情况下在EF 7中启用了延迟加载。 这是为了减少不必要的数据库旅行。
您可以使用ThenInclude
加载相关实体
using (var db = new DbContext())
{
var query = db.PrintServer.Include(s => s.PrintServerSupport)
.ThenInclude(p => p.Manufacturer);
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.