实体框架 4.1 幽灵列
我目前在使用 EF4.1 时遇到一些问题。 SQL 的生成似乎与我期望根据我的类生成的内容不匹配。我有以下类(这只是一个较大集合的较小集合,但是,这就是我似乎遇到问题的地方)...
public class CustomEntityContext : DbContext
{
public CustomEntityContext()
:base(ConfigurationManager.ConnectionStrings["DBConnection"].ConnectionString) {}
public DbSet<Person> People { get; set; }
public DbSet<Occurrence> Occurrences { get; set; }
public DbSet<OccurrenceSecurity> OccurrenceSecurities { get; set; }
}
[DataContract(IsReference = true)]
[Table("Occurrence")]
public class Occurrence
{
[DataMember] public int ID { get; set; }
[DataMember] public string Number { get; set; }
[DataMember] public bool? IsMOR { get; set; }
[DataMember] public bool? IsConfidential { get; set; }
[DataMember] public int? IncidentID { get; set; }
[DataMember] public bool? CanPublish { get; set; }
[DataMember] public bool? IsFeedbackRequired { get; set; }
[DataMember] public bool? IsRegulatorReport { get; set; }
[DataMember] public DateTime? RecordedDate { get; set; }
[DataMember] public DateTime? ReportedDate { get; set; }
[DataMember] public int? ReportTypeID { get; set; }
[DataMember] public bool? IsMain { get; set; }
[DataMember] public bool? IsRejected { get; set; }
[DataMember] public string Title { get; set; }
[DataMember] public byte[] Version { get; set; }
[DataMember] public string ReportDataXml { get; set; }
[DataMember] public int? LocationID { get; set; }
[DataMember, ForeignKey("RecordedByPersonID")] public Person Recorder { get; set; }
[DataMember, ForeignKey("ReportedByPersonID")] public Person Reporter { get; set; }
}
[DataContract(IsReference = true)]
[Table("OccurrenceSecurity")]
public class OccurrenceSecurity
{
[DataMember, Key, Column("PersonID", Order = 0)] public int PersonID { get; set; }
[DataMember, ForeignKey("PersonID")] public Person Person { get; set; }
[DataMember, Key, Column("OccurrenceID", Order = 1)] public int OccurrenceID { get; set;
[DataMember, ForeignKey("OccurrenceID")] public Occurrence Occurrence { get; set; }
}
[DataContract(IsReference = true)]
[Table("Person")]
public class Person
{
[DataMember] public int ID { get; set; }
[DataMember] public string FullName { get; set; }
//[DataMember] public Occurrence[] RecordedOccurrences { get; set; }
//[DataMember] public Occurrence[] ReportedOccurrences { get; set; }
//[DataMember] public OccurrenceSecurity[] OccurrenceSecurities { set; get; }
}
当我使用 Include 方法请求 OccurrenceSecurities 时,我要求包括事件和人物。随后,生成的 SQL 如下...
SELECT
[Extent1].[PersonID] AS [PersonID],
[Extent1].[OccurrenceID] AS [OccurrenceID],
[Extent2].[ID] AS [ID],
[Extent2].[FullName] AS [FullName],
[Extent3].[ID] AS [ID1],
[Extent3].[Number] AS [Number],
[Extent3].[IsMOR] AS [IsMOR],
[Extent3].[IsConfidential] AS [IsConfidential],
[Extent3].[IncidentID] AS [IncidentID],
[Extent3].[CanPublish] AS [CanPublish],
[Extent3].[IsFeedbackRequired] AS [IsFeedbackRequired],
[Extent3].[IsRegulatorReport] AS [IsRegulatorReport],
[Extent3].[RecordedByPersonID] AS [RecordedByPersonID],
[Extent3].[RecordedDate] AS [RecordedDate],
[Extent3].[ReportedByPersonID] AS [ReportedByPersonID],
[Extent3].[ReportedDate] AS [ReportedDate],
[Extent3].[ReportTypeID] AS [ReportTypeID],
[Extent3].[IsMain] AS [IsMain],
[Extent3].[IsRejected] AS [IsRejected],
[Extent3].[Title] AS [Title],
[Extent3].[Version] AS [Version],
[Extent3].[ReportDataXml] AS [ReportDataXml],
[Extent3].[LocationID] AS [LocationID],
[Extent3].[Person_ID] AS [Person_ID], -- Where does this come from?
[Extent3].[Person_ID1] AS [Person_ID1] -- Where does this come from?
FROM [dbo].[OccurrenceSecurity] AS [Extent1]
INNER JOIN [dbo].[Person] AS [Extent2] ON [Extent1].[PersonID] = [Extent2].[ID]
LEFT OUTER JOIN [dbo].[Occurrence] AS [Extent3] ON [Extent1].[OccurrenceID] = [Extent3].[ID]
如您所见,Select 块末尾有 2 列,分别选择 Person_ID 和 Person_ID1。这些不存在于我的基础表或我的对象中。
有谁知道它们从哪里来以及为什么在那里?
另外,我知道这是一个多对多关系,但是,OccurrenceSecurities 表/类将扩展以容纳更多数据。
谢谢, 大卫
I am currently having some issues with EF4.1. The generation of the the SQL doesn't seem to match what I expect to be generated based on my classes. I have the following classes (This is just a smaller set of a bigger collection, however, this is where I appear to be having issues)...
public class CustomEntityContext : DbContext
{
public CustomEntityContext()
:base(ConfigurationManager.ConnectionStrings["DBConnection"].ConnectionString) {}
public DbSet<Person> People { get; set; }
public DbSet<Occurrence> Occurrences { get; set; }
public DbSet<OccurrenceSecurity> OccurrenceSecurities { get; set; }
}
[DataContract(IsReference = true)]
[Table("Occurrence")]
public class Occurrence
{
[DataMember] public int ID { get; set; }
[DataMember] public string Number { get; set; }
[DataMember] public bool? IsMOR { get; set; }
[DataMember] public bool? IsConfidential { get; set; }
[DataMember] public int? IncidentID { get; set; }
[DataMember] public bool? CanPublish { get; set; }
[DataMember] public bool? IsFeedbackRequired { get; set; }
[DataMember] public bool? IsRegulatorReport { get; set; }
[DataMember] public DateTime? RecordedDate { get; set; }
[DataMember] public DateTime? ReportedDate { get; set; }
[DataMember] public int? ReportTypeID { get; set; }
[DataMember] public bool? IsMain { get; set; }
[DataMember] public bool? IsRejected { get; set; }
[DataMember] public string Title { get; set; }
[DataMember] public byte[] Version { get; set; }
[DataMember] public string ReportDataXml { get; set; }
[DataMember] public int? LocationID { get; set; }
[DataMember, ForeignKey("RecordedByPersonID")] public Person Recorder { get; set; }
[DataMember, ForeignKey("ReportedByPersonID")] public Person Reporter { get; set; }
}
[DataContract(IsReference = true)]
[Table("OccurrenceSecurity")]
public class OccurrenceSecurity
{
[DataMember, Key, Column("PersonID", Order = 0)] public int PersonID { get; set; }
[DataMember, ForeignKey("PersonID")] public Person Person { get; set; }
[DataMember, Key, Column("OccurrenceID", Order = 1)] public int OccurrenceID { get; set;
[DataMember, ForeignKey("OccurrenceID")] public Occurrence Occurrence { get; set; }
}
[DataContract(IsReference = true)]
[Table("Person")]
public class Person
{
[DataMember] public int ID { get; set; }
[DataMember] public string FullName { get; set; }
//[DataMember] public Occurrence[] RecordedOccurrences { get; set; }
//[DataMember] public Occurrence[] ReportedOccurrences { get; set; }
//[DataMember] public OccurrenceSecurity[] OccurrenceSecurities { set; get; }
}
When I ask for the OccurrenceSecurities, with the Include methods, I ask to include both the Occurrence and Person. Subsequently, the SQL that is generated is as follows...
SELECT
[Extent1].[PersonID] AS [PersonID],
[Extent1].[OccurrenceID] AS [OccurrenceID],
[Extent2].[ID] AS [ID],
[Extent2].[FullName] AS [FullName],
[Extent3].[ID] AS [ID1],
[Extent3].[Number] AS [Number],
[Extent3].[IsMOR] AS [IsMOR],
[Extent3].[IsConfidential] AS [IsConfidential],
[Extent3].[IncidentID] AS [IncidentID],
[Extent3].[CanPublish] AS [CanPublish],
[Extent3].[IsFeedbackRequired] AS [IsFeedbackRequired],
[Extent3].[IsRegulatorReport] AS [IsRegulatorReport],
[Extent3].[RecordedByPersonID] AS [RecordedByPersonID],
[Extent3].[RecordedDate] AS [RecordedDate],
[Extent3].[ReportedByPersonID] AS [ReportedByPersonID],
[Extent3].[ReportedDate] AS [ReportedDate],
[Extent3].[ReportTypeID] AS [ReportTypeID],
[Extent3].[IsMain] AS [IsMain],
[Extent3].[IsRejected] AS [IsRejected],
[Extent3].[Title] AS [Title],
[Extent3].[Version] AS [Version],
[Extent3].[ReportDataXml] AS [ReportDataXml],
[Extent3].[LocationID] AS [LocationID],
[Extent3].[Person_ID] AS [Person_ID], -- Where does this come from?
[Extent3].[Person_ID1] AS [Person_ID1] -- Where does this come from?
FROM [dbo].[OccurrenceSecurity] AS [Extent1]
INNER JOIN [dbo].[Person] AS [Extent2] ON [Extent1].[PersonID] = [Extent2].[ID]
LEFT OUTER JOIN [dbo].[Occurrence] AS [Extent3] ON [Extent1].[OccurrenceID] = [Extent3].[ID]
As you can see, there are 2 columns at the end of the Select block which are selecting Person_ID and Person_ID1. These don't exist in my underlying table, or in my object.
Does anyone know where these come from and why they are there?
Also, I am aware that this is a Many-to-Many relationship, however, the OccurrenceSecurities table/class will extend to hold more data.
Thanks,
David
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
EF 将使用这些额外的列从查询结果构建对象图。通过使用
Include
,您是在说“我只想执行一个存储命令,但我想检索许多对象”。 EF 不是使用多个结果集(并非所有后备存储都支持),而是在您查询A.Include("BC")
时发出带有如下结果的查询:然后将这些行缝合在一起制作两个
A
、3 个B
和 7 个C
,并具有适当的关系。我猜测,您显示的特定额外列是 EF 在拼接过程中使用的。
These extra columns will be used by EF to construct the object graph from the query results. By using
Include
, you are saying "I want to only execute one store command, but I want to retrieve many objects". Rather than using multiple resultsets (which not all backing stores will support), EF instead issues a query with results like this, when you queryA.Include("B.C")
:and then stitches together these rows to make two
A
, 3B
s and 7C
s, with the appropriate relationships.The particular extra columns you show are used by EF in the stitching-together process, is my guess.