Entity Framework 4.1 Ghost Columns - PullRequest
       13

Entity Framework 4.1 Ghost Columns

5 голосов
/ 10 февраля 2012

У меня в настоящее время есть некоторые проблемы с 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; } 
}

Когда я запрашиваю 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 будет расширяться.держать больше данных.

Спасибо, Дэвид

1 Ответ

2 голосов
/ 10 февраля 2012

с помощью методов Включить я прошу включить и Происшествие, и Персона

Эти дополнительные столбцы будут использоваться EF для построения графа объектов из результатов запроса. Используя Include, вы говорите: «Я хочу выполнить только одну команду хранилища, но я хочу получить много объектов». Вместо того чтобы использовать несколько наборов результатов (которые поддерживаются не во всех хранилищах), EF вместо этого выдает запрос с такими результатами, когда вы запрашиваете A.Include("B.C"):

columns for A1 columns for B1 columns for C1
columns for A1 columns for B1 columns for C2
columns for A1 columns for B1 columns for C3
columns for A1 columns for B2 columns for C4
columns for A1 columns for B2 columns for C5
columns for A2 columns for B3 columns for C6
columns for A2 columns for B3 columns for C7

и затем сшивает вместе эти строки, чтобы получить два A, 3 B с и 7 C с, с соответствующими отношениями.

Я полагаю, что показанные вами дополнительные столбцы используются EF в процессе сшивания.

...