EF dbcontext 在 dynamo 自定义节点中返回一个空的 dbset
Posted
技术标签:
【中文标题】EF dbcontext 在 dynamo 自定义节点中返回一个空的 dbset【英文标题】:EF dbcontext return an empty dbset in dynamo custom node 【发布时间】:2021-06-19 05:11:39 【问题描述】:我想在 Dynamo 节点中创建一个下拉列表来选择一个项目并返回属性。
我有一个解决方案,其中有 3 个项目。一个项目是数据库的连接器,由其他两个项目中的任何一个使用。
另外两个项目本质上是 UI,用于显示从数据库中获取的项目。一个是 WPF 应用程序,另一个是 Dynamo 节点。
当我使用 WPF 应用程序时,连接器 dbcontext 中的数据返回带有值的 dbset。但是当我将连接器与 Dynamo 节点一起使用时,连接器返回一个空的数据库集。因此节点中的组合框为空。
连接器 dbcontext
using Autodesk.DesignScript.Runtime;
using System.Data.Entity;
namespace ConnectToDB
[IsVisibleInDynamoLibrary(false)]
public partial class ShapesModelContext : DbContext
[IsVisibleInDynamoLibrary(false)]
public ShapesModelContext()
: base("ShapesModelContext")
public DbSet<C> C get; set;
public DbSet<C_m> C_m get; set;
public DbSet<HP> HPs get; set;
public DbSet<HP_m> HP_m get; set;
public DbSet<HSS> HSSes get; set;
public DbSet<HSS_m> HSS_m get; set;
public DbSet<L> L get; set;
public DbSet<L_m> L_m get; set;
public DbSet<M> M get; set;
public DbSet<M_m> M_m get; set;
public DbSet<MC> MCs get; set;
public DbSet<MC_m> MC_m get; set;
public DbSet<MT> MTs get; set;
public DbSet<MT_m> MT_m get; set;
public DbSet<PIPE> PIPEs get; set;
public DbSet<PIPE_m> PIPE_m get; set;
public DbSet<S> S get; set;
public DbSet<S_m> S_m get; set;
public DbSet<ShapesID> ShapesIDs get; set;
public DbSet<ST> STs get; set;
public DbSet<ST_m> ST_m get; set;
public DbSet<sysdiagram> sysdiagrams get; set;
public DbSet<TwoL> TwoLs get; set;
public DbSet<TwoL_m> TwoL_m get; set;
public DbSet<W> W get; set;
public DbSet<W_m> W_m get; set;
public DbSet<WT> WTs get; set;
public DbSet<WT_m> WT_m get; set;
protected override void OnModelCreating(DbModelBuilder modelBuilder)
modelBuilder.Entity<ShapesID>()
.HasOptional(e => e.C)
.WithRequired(e => e.ShapesID);
modelBuilder.Entity<ShapesID>()
.HasOptional(e => e.HP)
.WithRequired(e => e.ShapesID);
modelBuilder.Entity<ShapesID>()
.HasOptional(e => e.HSS)
.WithRequired(e => e.ShapesID);
modelBuilder.Entity<ShapesID>()
.HasOptional(e => e.L)
.WithRequired(e => e.ShapesID);
modelBuilder.Entity<ShapesID>()
.HasOptional(e => e.M)
.WithRequired(e => e.ShapesID);
modelBuilder.Entity<ShapesID>()
.HasOptional(e => e.MC)
.WithRequired(e => e.ShapesID);
modelBuilder.Entity<ShapesID>()
.HasOptional(e => e.MT)
.WithRequired(e => e.ShapesID);
modelBuilder.Entity<ShapesID>()
.HasOptional(e => e.PIPE)
.WithRequired(e => e.ShapesID);
modelBuilder.Entity<ShapesID>()
.HasOptional(e => e.S)
.WithRequired(e => e.ShapesID);
modelBuilder.Entity<ShapesID>()
.HasOptional(e => e.ST)
.WithRequired(e => e.ShapesID);
modelBuilder.Entity<ShapesID>()
.HasOptional(e => e.TwoL)
.WithRequired(e => e.ShapesID);
modelBuilder.Entity<ShapesID>()
.HasOptional(e => e.W)
.WithRequired(e => e.ShapesID);
modelBuilder.Entity<ShapesID>()
.HasOptional(e => e.WT)
.WithRequired(e => e.ShapesID);
视图模型和获取数据的方法。
using System.Collections.Generic;
using Newtonsoft.Json;
namespace ConnectToDB
public class AISC_ShapesViewModel
private List<string> _Shapes;
public List<string> Shapes
get
return _Shapes;
set
_Shapes = value;
public List<string> LoadSections()
List<string> thaColl = new List<string>();
using (var context = new ShapesModelContext())
var sections = context.ShapesIDs;
foreach (var section in context.ShapesIDs)
thaColl.Add(section.EDI_Std_Nomenclature);
return Shapes = thaColl;
在组合框中正确显示数据的 WPF 应用程序。
<Window x:Class="WPFUI.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WPFUI"
xmlns:vm="clr-namespace:ConnectToDB;assembly=ConnectToDB"
Loaded="Main_Loaded"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Window.Resources>
<vm:AISC_ShapesViewModel x:Key="thaMidClass"/>
</Window.Resources>
<Grid DataContext="Binding Mode=OneWay, Source=StaticResource thaMidClass">
<ComboBox x:Name="comboBox" HorizontalAlignment="Left" Margin="10,10,0,0" VerticalAlignment="Top" Width="120" ItemsSource="Binding Shapes"/>
<Label x:Name="section" Content="Binding SelectedItem, ElementName=comboBox" HorizontalAlignment="Left" Margin="173,10,0,0" VerticalAlignment="Top" Width="291" Height="22" FontSize="10"/>
</Grid>
</Window>
我的 Dynamo 节点的用户控件不显示数据。
<UserControl x:Class="DynamoUI.Dynamo_UI"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:DynamoUI"
xmlns:vm="clr-namespace:ConnectToDB;assembly=ConnectToDB"
Loaded="Comboloaded"
mc:Ignorable="d" Height="73.5" Width="219.5">
<UserControl.Resources>
<vm:AISC_ShapesViewModel x:Key="thaMidClass"/>
</UserControl.Resources>
<Grid DataContext="StaticResource thaMidClass">
<ComboBox x:Name="comboBox" HorizontalAlignment="Left" Margin="10,10,0,0" VerticalAlignment="Top" Width="193" ItemsSource="Binding Path=Shapes"/>
</Grid>
</UserControl>
节点模型。
using CoreNodeModels;
using Dynamo.Graph.Nodes;
using Newtonsoft.Json;
namespace DynamoUI
[NodeName("AISC Shapes")]
[NodeDescription("Query AISC shapes database")]
[NodeCategory("AISC.Shapes Node")]
//[InPortNames("A")]
//[InPortTypes("List")]
//[InPortDescriptions("List A")]
[OutPortNames("Output")]
[OutPortTypes("Dictionary")]
[OutPortDescriptions("Shape properties dictionary")]
[IsDesignScriptCompatible]
class AISC_Shape_Node_Model: NodeModel
[JsonConstructor]
public AISC_Shape_Node_Model()
RegisterAllPorts();
节点视图。
using Dynamo.Controls;
using Dynamo.Wpf;
namespace DynamoUI
class AISC_Shape_Node_View : INodeViewCustomization<AISC_Shape_Node_Model>
public void CustomizeView(AISC_Shape_Node_Model model, NodeView nodeView)
var ui = new Dynamo_UI();
nodeView.inputGrid.Children.Add(ui);
ui.DataContext = model;
public void Dispose()
连接字符串。
<connectionStrings>
<add name="ShapesModelContext" connectionString="data source=MyDatabase;initial catalog=AISC_Shapes_V15;integrated security=True;MultipleActiveResultSets=True;App=EntityFramework" providerName="System.Data.SqlClient" />
</connectionStrings>
带有 Dynamo 节点。
使用 WPF 应用程序。
每次使用WPF前端时,都会调用这个方法。
public List<string> LoadSections()
List<string> thaColl = new List<string>();
using (var context = new ShapesModelContext())
var sections = context.ShapesIDs;
foreach (var section in context.ShapesIDs)
thaColl.Add(section.EDI_Std_Nomenclature);
return Shapes = thaColl;
并且,在调试步骤中,我们可以看到创建了从 EF DbContext 继承的“ShapesModelContext”,并将 ShapesIDs DbSet 分配给了部分。代码进入 for 循环并遍历 DbSet。
但是,当我使用 Dynamo NodeModel 作为前端时,会执行相同的代码,但在 for 循环中,它会检查 DbSet 并立即退出循环,因为 DbSet 为空。
【问题讨论】:
这 3 个项目的连接字符串是什么?通常如果连接字符串不同,结果也会不同。 所有项目的连接字符串都相同。我将一个 ui 项目切换到另一个。当我使用 WPF 应用程序时,它工作正常,但当我使用 Dynamo 节点时,组合框为空。 为什么DataContext不同? 我对 WPF 应用程序和 Dynamo 节点使用相同的 dbcontext。为什么你认为有不同? 1)问题在于 Dynamo 使用自己的连接字符串。连接字符串指向:
Data Source=(localdb)\mssqllocaldb
初始目录名称由在 DbContext 中找到的连接字符串名称定义。
Initial Catalog=ShapesModelContext
因此我更改了我的 LoadSections() 方法以指定正确的连接字符串。
原来的代码是:
public List<string> LoadSections()
List<string> thaColl = new List<string>();
using (var context = new ShapesModelContext())
var sections = context.ShapesIDs;
foreach (var section in context.ShapesIDs)
thaColl.Add(section.EDI_Std_Nomenclature);
return Shapes = thaColl;
现在添加了连接字符串。
using (var context = new ShapesModelContext())
context.Database.Connection.ConnectionString = "data source=XXXXX;initial catalog=XXXXXXXX;integrated security=True;MultipleActiveResultSets=True;App=EntityFramework";
var sections = context.ShapesIDs;
foreach (var section in sections)
thaColl.Add(section.EDI_Std_Nomenclature);
return Shapes = thaColl;
【讨论】:
以上是关于EF dbcontext 在 dynamo 自定义节点中返回一个空的 dbset的主要内容,如果未能解决你的问题,请参考以下文章
如何在 EF Core 5 中为自定义 SQL 配置导航属性
如何在 EF Core Code First 中自定义迁移生成?