【发布时间】:2020-01-23 05:08:32
【问题描述】:
我有 2 个表 TableA 和 TableB 与 ID 列链接。这是一个 1:N 的关系。我有以下代码
var query = from b in _ctx.TableA
.Where(b => b.Flag == true)
.Include(c => c.TableB)
select b;
这会产生以下选择语句,在主从网格中正确显示我的数据:
SELECT
[Project1].[C5] AS [C1],
[Project1].[Id] AS [Id],
[Project1].[ProductType] AS [ProductType],
[Project1].[Ccy] AS [Ccy],
[Project1].[Flag] AS [Flag],
[Project1].[C6] AS [C6],
[Project1].[Id1] AS [Id1]
FROM ( SELECT
[Extent1].[Id] AS [Id],
[Extent1].[Description] AS [Description],
[Extent1].[ProductType] AS [ProductType],
[Extent1].[Flag] AS [Flag],
1 AS [C5],
[Extent2].[Id] AS [Id1],
[Extent2].[Ccy] AS [Ccy],
CASE WHEN ([Extent2].[Id] IS NULL) THEN CAST(NULL AS int) ELSE 1 END AS [C6]
FROM [dbo].[TableA] AS [Extent1]
LEFT OUTER JOIN [dbo].[TableB] AS [Extent2] ON [Extent1].[Id] = [Extent2].[Id]
WHERE (1 = [Extent1].[Flag]) AND ([Extent1].[Flag] IS NOT NULL)
) AS [Project1]
ORDER BY [Project1].[Id] ASC, [Project1].[C6] ASC
现在,我想过滤掉我的导航属性 (TableB)。我尝试了以下 3 种方法,并且通过所有 3 种方法得到了以下 SQL,但它缺少 TableA 中的列,例如 ProductType 和 Ccy。
var query = from b in _ctx.TableA
.Where(b => b.Flag == true)
.Include(c => c.TableB).Select(o => o.TableB.Where(od => od.Ccy == "USD"))
select b;
var query = from b in _ctx.TableA
.Where(b => b.Flag == true)
.Include(c => c.TableB)
.SelectMany(o => o.TableB.Where(od => od.Ccy == "USD"))
select b;
var query = from p in _ctx.TableA
join ps in _ctx.TableB on p.Id equals ps.Id
where ps.Ccy == "USD"
select new { p, ps };
SELECT [Project1].[Id] AS [Id],
[Project1].[C1] AS [C1],
[Project1].[Id1] AS [Id1],
[Project1].[Ccy] AS [Ccy],
FROM ( SELECT
[Extent1].[Id] AS [Id],
[Extent2].[Id] AS [Id1],
[Extent2].[Ccy] AS [Ccy],
CASE WHEN ([Extent2].[Id] IS NULL) THEN CAST(NULL AS int) ELSE 1 END AS [C1]
FROM [dbo].[TableA] AS [Extent1]
LEFT OUTER JOIN [dbo].[TableB] AS [Extent2]
ON ([Extent1].[Id] = [Extent2].[Id])
AND ('USD' = [Extent2].[Ccy]) AND ([Extent2].[Ccy] IS NOT NULL)
WHERE (1 = [Extent1].[Flag]) AND ([Extent1].[Flag] IS NOT NULL)
) AS [Project1]
ORDER BY [Project1].[Id] ASC, [Project1].[C1] ASC
如何修改上述 3 个查询之一以包含这些列:
[Project1].[ProductType] AS [ProductType],
[Project1].[Ccy] AS [Ccy],
[Project1].[Flag] AS [Flag],
我了解导航属性并不意味着能够过滤,但这些查询是正确的,除了 TableA 上缺少的列。
我使用表格来简化代码。我将详细说明我是如何显示主从网格的,这样您就可以看到正在使用的数据上下文。我简化了实际代码,所以只有相关的细节。希望这将阐明当前代码的工作方式。我不确定我应该如何修改 xaml 以使绑定正常工作而不会出现这些错误:
[Table("viewA")]
public class Master
{
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
public Investment()
{
Prices = new HashSet<CcyHistory>();
}
[StringLength(150)]
[Column(TypeName = "varchar")]
public string Id { get; set; }
[StringLength(150)]
[Column(TypeName = "varchar")]
public string Description { get; set; }
public bool? Flag { get; set; }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public ICollection<CcyHistory> Details { get; set; }
}
[Table("viewB")]
public class CcyHistory
{
[Key]
[StringLength(150)]
[Column(Order = 0, TypeName = "varchar")]
public string Id { get; set; }
[StringLength(10)]
[Column(TypeName = "varchar")]
public string Ccy { get; set; }
public virtual Master Master { get; set; }
}
public partial class MyContext : DbContext
{
public MyContext()
: base("name=MyContext")
{
Database.SetInitializer<MyContext>(null);
}
public virtual DbSet<Master> Masters { get; set; }
public virtual DbSet<CcyHistory> Details { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
}
}
public partial class MyView : Window
{
MyViewModel viewModel;
public MyContext _ctx = new MyContext();
.......
public MyView()
{
viewModel = new MyViewModel();
InitializeComponent();
DataContext = viewModel;
}
private async void Window_Loaded(object sender, RoutedEventArgs e)
{
System.Windows.Data.CollectionViewSource myViewSource = ((System.Windows.Data.CollectionViewSource)(this.FindResource("myViewSource")));
// this works fine
var query = from b in _ctx.Masters
.Where(b => b.Flag == true)
.Include(c => c.Details)
select b;
// this query cannot be bound to xaml
//var query = from a in _ctx.Masters
// .Where(a => a.Flag == true)
// .Select(a => new
// {
// Details = a,
// USD = a.Details.Where(od => od.Ccy == "USD").ToList()
// })
// select a;
myViewSource.Source = query.ToList();
XAML:
<Window.Resources>
<CollectionViewSource x:Key="myViewSource" d:DesignSource="d:DesignInstance {x:Type local:Masters},CreatList=True}"/>
<CollectionViewSource x:Key="myDetailsViewSource" Source="{Binding Details, Source={StaticResource myViewSource}}">
</CollectionViewSource>
</Window.Resources>
.....
<Grid Name="MyGrid" DataContext="{StaticResource myViewSource}" >
<igDP:XamDataGrid x:Name="masterGrid" Grid.Row="1" DataSource="{Binding}" IsSynchronizedWithCurrentItem="True">
<igDP:XamDataGrid.FieldSettings>
<igDP:FieldSettings Width="Auto" AllowEdit="False"/>
</igDP:XamDataGrid.FieldSettings>
<igDP:XamDataGrid.FieldLayoutSettings>
<igDP:FieldLayoutSettings AutoGenerateFields="False" SelectionTypeRecord="Extended" SelectionTypeCell="None" />
</igDP:XamDataGrid.FieldLayoutSettings>
<igDP:XamDataGrid.FieldLayouts>
<igDP:FieldLayout>
<igDP:UnboundField Name="ID" BindingPath="Id" BindingMode="TwoWay">
<igDP:UnboundField.Settings>
<igDP:FieldSettings CellClickAction="SelectRecord">
</igDP:FieldSettings>
</igDP:UnboundField.Settings>
</igDP:UnboundField>
<igDP:UnboundField Name="Description" BindingPath="Description" BindingMode="TwoWay">
<igDP:UnboundField.Settings>
<igDP:FieldSettings CellClickAction="SelectRecord">
</igDP:FieldSettings>
</igDP:UnboundField.Settings>
</igDP:UnboundField>
<igDP:UnboundField Name="Held" BindingPath ="Flag">
<igDP:Field.Settings>
<igDP:FieldSettings CellClickAction="SelectRecord"/>
</igDP:Field.Settings>
</igDP:UnboundField>
</igDP:FieldLayout>
</igDP:XamDataGrid.FieldLayouts>
</igDP:XamDataGrid>
<igDP:XamDataGrid x:Name="detailsDataGrid" Grid.Row="2" DataSource="{Binding Source={StaticResource myDetailsViewSource}}" >
<igDP:XamDataGrid.FieldSettings>
<igDP:FieldSettings Width="Auto" AllowEdit="False"/>
</igDP:XamDataGrid.FieldSettings>
<igDP:XamDataGrid.FieldLayoutSettings>
<igDP:FieldLayoutSettings AutoGenerateFields="False" SelectionTypeRecord="Extended" SelectionTypeCell="None" />
</igDP:XamDataGrid.FieldLayoutSettings>
<igDP:XamDataGrid.FieldLayouts>
<igDP:FieldLayout>
<igDP:UnboundField Name="ID" BindingPath="Id" Width="Auto" BindingMode="TwoWay">
<igDP:UnboundField.Settings>
<igDP:FieldSettings AllowEdit="False" CellClickAction="SelectRecord">
</igDP:FieldSettings>
</igDP:UnboundField.Settings>
</igDP:UnboundField>
<igDP:UnboundField Name="Ccy" BindingPath="Ccy" Width="Auto" >
<igDP:Field.Settings>
<igDP:FieldSettings AllowEdit="False" />
</igDP:Field.Settings>
</igDP:UnboundField>
</igDP:FieldLayout>
</igDP:XamDataGrid.FieldLayouts>
</igDP:XamDataGrid>
</Grid>
例如,我遇到的错误之一是:
System.Windows.Data 错误:40:BindingExpression 路径错误:在“对象”''f__AnonymousType02' (HashCode=580396885)'. BindingExpression:Path=Description; DataItem='<>f__AnonymousType02'(HashCode=580396885)上找不到“描述”属性;目标元素是“ValueHolder”(HashCode=62039823);目标属性是“值”(类型“对象”)
【问题讨论】:
标签: entity-framework linq