我在自定义“地图窗口小部件”组件中使用了清晰的地图。要填充地图,我想使用实体框架,它位于单独的DLL中。如果我创建一个地图,然后获取数据,这可以正常工作。
public void loadMap() {
var map = new MapWidget(); // Create a new widget which internally uses SharpMap
map.AddCountriesLayer(); // Load the map background from .shp file
var data = new IPService.GetPointsForMap(); // Gets IP address from entity framework, inside "domain.dll"
map.AddDots(data); // Add dots
}
但是,如果我先获取数据,然后制作地图,那么事情就会破裂:
public void loadMap() {
var data = new IPService.GetPointsForMap(); // Accessing entity framework before sharpmap
var map = new MapWidget();
map.AddCountriesLayer();
map.AddDots(data);
}
结果
System.NotSupportedException "The invoked member is not supported in a dynamic assembly."
at System.Reflection.Emit.InternalAssemblyBuilder.GetExportedTypes()
at GeoAPI.GeometryServiceProvider.ReflectInstance()
at GeoAPI.GeometryServiceProvider.get_Instance()
at SharpMap.Data.Providers.ShapeFile.set_SRID(Int32 value) in C:\dev\DLLs\SharpMap Source\Trunk\SharpMap\Data\Providers\ShapeFile.cs:line 859
at SharpMap.Data.Providers.ShapeFile.ParseProjection() in C:\dev\DLLs\SharpMap Source\Trunk\SharpMap\Data\Providers\ShapeFile.cs:line 978
at SharpMap.Data.Providers.ShapeFile..ctor(String filename, Boolean fileBasedIndex) in C:\dev\DLLs\SharpMap Source\Trunk\SharpMap\Data\Providers\ShapeFile.cs:line 302
at Dashboard.Widgets.MapWidget.AddCountriesLayer() in c:\dev\Dashboard\v1\Dashboard\Classes\Widgets\Generic\MapWidget.cs:line 86
这到底是怎么回事?为什么要首先使用实体框架呢?
要解决此问题,我将其添加到program.cs,以强制首先加载窗口小部件。
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
// Hack to force SharpMap to register before entity framework
var widget = new Widgets.MapWidget();
widget.Update();
Application.Run(new DashboardForm());
}
然而,我不喜欢它 - 它看起来很脆弱,我不喜欢“巧合编码”。我能做些什么来解决它吗?
我发现了这篇博文:http://elegantcode.com/2010/01/28/the-entity-framework-and-the-the-invoked-member-is-not-supported-in-a-dynamic-assembly-exception/ 我将域程序集添加到connectionString
我的项目结构如下:
所以我的问题是:
感谢您的阅读,请让我澄清一下我是否还不清楚。
答案 0 :(得分:2)
我有一个非常类似的问题,但我没有使用实体框架(我正在使用NHibernate),所以,我发现这毕竟不是代理对象问题。
我也不喜欢“巧合编码”,但我认为通过调用new MapWidget()
,一些与GeoApi相关的初始化是在内部执行的 - 因为SharpMap内部使用了GeoApi。
在我的情况下,我没有直接使用地图,我只是使用NHibernate在我的数据库中插入一些地理数据,我得到了完全相同的堆栈跟踪,所以我认为这可能是同样的问题。
尽管我讨厌它,但我有这样的事情:
// my object to be persisted using NHibernate
var myObj = new MyObj();
// add polygon of type GeoAPI.Geometries.IGeometry
myObj.CoveredArea = myGeoFactory.CreatePolygonArea(/* ... */);
// use NHibernate to save my obj
sessioNScope.Save(myObj); // <- throws NotSupportedException here
它给了我一个与你一样的例外。将其更改为
后// Ignore this line: hack to initialize GeoApi
new Map();
// my object to be persisted using NHibernate
var myObj = new MyObj();
// add polygon of type GeoAPI.Geometries.IGeometry
myObj.CoveredArea = myGeoFactory.CreatePolygonArea(/* ... */);
// use NHibernate to save my obj
sessioNScope.Save(myObj);
它运作得很好。在我的情况下,我使用了new Map()
而不是new MapWidget()
,因为它是winforms应用程序。
TLDR:将其视为执行初始化
的黑客攻击答案 1 :(得分:1)
这很可能是由于EF生成的动态代理造成的。我不熟悉SharpMap,所以我无法评论它在EF之前对它进行初始化有什么影响,但你应该能够通过禁用代理创建来避免异常:
context.Configuration.ProxyCreationEnabled = false;
请注意,这将禁用延迟加载和更改跟踪,因此请首先仔细阅读本文:http://msdn.microsoft.com/en-us/data/jj592886