我相信大多数人会问为什么不行。我想通过询问为什么这会起作用来混淆它。实体框架 - 为什么这会起作用?
private SmokeFireDBEntities dbContext = null;
private IList<MemberResponse> gridData = new List<MemberResponse>();
private void UserControl_Initialized(object sender, EventArgs e)
{
this.dbContext = new SmokeFireDBEntities();
var members = from m in dbContext.Members
where new[] { "A", "P", "S", "J" }.Contains(m.Class.ShortName)
orderby m.Line
select m;
foreach (Member m in members)
{
MemberResponse mr = new MemberResponse();
mr.MemberID = m.ID;
mr.Member = m;
this.gridData.Add(mr);
}
PercentageGrid.ItemsSource = this.gridData;
}
private void SaveButton_Click(object sender, RoutedEventArgs e)
{
AlarmTotal at = new AlarmTotal();
at.Month = Convert.ToByte(this.MonthField.Text);
at.Year = Convert.ToInt16(this.YearField.Text);
at.NumAlarms = Convert.ToInt16(this.TotalAlarmsField.Text);
this.dbContext.AlarmTotals.AddObject(at);
this.dbContext.SaveChanges();
// WHY IS THE FOLLOWING CODE NOT NECESSARY???
//foreach (MemberResponse mr in this.PercentageGrid.Items)
//{
// mr.AlarmTotalID = at.ID;
// this.dbContext.MemberResponses.AddObject(mr);
//}
//this.dbContext.SaveChanges();
}
<UserControl.Resources>
<DataTemplate x:Key="NameColumnTemplate">
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Path=Member.LastName}" />
<TextBlock Text=", " />
<TextBlock Text="{Binding Path=Member.FirstName}" />
</StackPanel>
</DataTemplate>
<DataTemplate x:Key="InputColumnTemplate">
<StackPanel Orientation="Horizontal">
<TextBox Text="{Binding Path=NumAttended}" Name="MonthResponse" Width="60" />
</StackPanel>
</DataTemplate>
</UserControl.Resources>
<Grid Background="WhiteSmoke" Height="353" Width="509">
<TextBox Height="23" HorizontalAlignment="Left" Margin="12,33,0,0" Name="MonthField" VerticalAlignment="Top" Width="75" />
<TextBox Height="23" HorizontalAlignment="Left" Margin="93,33,0,0" Name="YearField" VerticalAlignment="Top" Width="59" />
<TextBox Height="23" HorizontalAlignment="Left" Margin="158,33,0,0" Name="TotalAlarmsField" VerticalAlignment="Top" Width="115" />
<ListView Margin="1,67,0,0" Name="PercentageGrid" ItemsSource="Binding" HorizontalAlignment="Stretch" Width="507" Height="286" VerticalAlignment="Stretch">
<ListView.View>
<GridView>
<GridView.Columns>
<GridViewColumn Header="Name" CellTemplate="{StaticResource NameColumnTemplate}" />
<GridViewColumn Header="Line#" DisplayMemberBinding="{Binding Path=Member.Line}" />
<GridViewColumn Header="Class" DisplayMemberBinding="{Binding Path=Member.Class.ShortName}" />
<GridViewColumn Header="Response" CellTemplate="{StaticResource InputColumnTemplate}" />
</GridView.Columns>
</GridView>
</ListView.View>
</ListView>
我已经删除了不必要的代码来缩短这一点。我对C#,.NET以及与之相关的一切都是全新的。我完全难以理解为什么这一切都可行。当我调用第一个dbContext.SaveChanges()将记录保存到“AlarmTotals”时,它也同时保存了所有“MemberResponse”记录,更令人惊讶的是填充了正确的AlarmTotals.ID字段。这个真的让我失望,我不明白这是如何运作的,看起来像是魔法。
任何洞察力和解释将不胜感激。我真的很想了解这里发生了什么。
是的,我确定正确的AlarmTotalID已添加到MemberResponse记录中。这令我惊讶的是比添加的记录更多,因为我没有办法让它为此获得正确的上下文。也许它只是使用最后添加的记录?我会跟进你关于断点的建议,看看我能否更好地理解正在发生的事情。谢谢 – 2012-03-30 01:38:34
也许在数据库中有一个默认或触发器应用这些更改? – surfen 2012-03-30 01:40:49
@NickSperling ands surfen:我同意这个答案。这是不可能的,'mr.AlarmTotalID'将被设置为你正在显示的代码中新创建的ID。您只需创建一个新的'AlarmTotal',您设置了三个标量属性(我猜这些不是FK属性),并且没有导航属性到另一个实体。没有其他实体提到新的'at'。设置AlarmTotalID必须发生在别的地方。也许断点测试会显示。 – Slauma 2012-03-30 11:37:42