DbSet.Cast ()错误:无法从非genericsDbSet为“实体”类型的对象创建DbSet
版本信息:
我正在使用C#4.5,Entity Framework 6.0和MEF。
代码和unit testing
我创建了一个测试项目来解释这个问题: https : //skydrive.live.com/redir?resid = E3C97EC293A34048!2234
请打开UnitTest项目并尝试运行TestIfItWorks()unit testing。
问题
我想将非genericsDbSet转换为其通用版本,但是我得到以下exception: InvalidCastException: Cannot create a DbSet from a non-generic DbSet for objects of type 'User'
:
var nonGeneric = context.Set(typeof(User)); var generic = nonGeneric.Cast(); //Exception in here
User类正在实现IUser,所以你会认为强制转换不应该是一个问题,除非DbSet代码被限制在具体的类中(我希望不是我需要创建一个围绕非genericsDbSet的包装器将它转换为genericsDbSet或找到当前DbSet实现的替代方案)。
如果你想知道为什么我使用接口,即使它们目前不受微软支持我给你一些解释(希望这会过滤掉“不要那样做”而不是提供解决方案的响应):
我正在使用MEF和EntityFramework创建一个松散耦合的数据层引擎,通过它我可以为每个项目提供实体(及其相应的配置)。 我一直在广泛使用Interfaces来定义引擎。 使用MEF在运行时发现元数据和上下文中实体的具体实现。
摘自代码
[TestMethod] public void TestIfItWorks() { //TODO: Please open the App.Config and change the PluginsPath to match the Plugins folder in your machine. using (var dbContext = new MyContext()) //Please ignore this line for now. This was UnitOfWork which I replaced with Context to create a simple unit test { dbContext.Setup(); //Please ignore this line for now. This was part of UnitOfWork which I moved to here to create a simple unit test //The purpose of all these is to be able to read and write user info from/to database while User class is defined in an external assembly //but we can import it by MEF using IUser interface. //Failed Attempt# 1: Use User class directly! This doesnt work because User is in an external class which we dont have reference to //var failedAttempt1 = dbContext.Set(); //Failed Attempt# 2: But the good thing is that we have access to IUser and its exports //then lets get a DbSet instead var failedAttempt2 = dbContext.Set(); try { var throwsException2 = failedAttempt2.FirstOrDefault(); } catch (InvalidOperationException ex) { //InvalidOperationException: // The entity type IUser is not part of the model for the current context. // It also didnt work when I tried to define a class that inherits from EntityTypeConfigurationat TestImplementation } //Ok then lets do it differently this time. Lets get User type (that we know we have good configuration for) //from our Container and ask Context to give us the nonGeneric version var userImplementationType = Logic.Instance.GetExportedTypes().FirstOrDefault(); Assert.IsNotNull(userImplementationType, "We havn't been able to load TestImplementation into catalog. Please ensure the PluginsPath is set correctly at App.Config"); var nonGeneric = dbContext.Set(userImplementationType); // // This is working so far, we can add and remove records from database using // the nonGeneric version of DbSet. You can uncomment the following code block provide a unique ID // and test it yourself. // var newUser = Logic.Instance.New(); newUser.Id = "99"; newUser.UserName = "Aidin Sadighi"; nonGeneric.Add(newUser); try { dbContext.SaveChanges(); } catch (DbUpdateException ex) { //This is OK because most probably this is a duplicate user. Just increase the Id to make it unique. } //Failed Attempt#3: Cast non generic DbSet to generic try { //TODO: I need to fix this. Help me please var genericSet = nonGeneric.Cast(); } catch (InvalidCastException ex) { //Cannot create a DbSet from a non-generic DbSet for objects of type 'User'. throw; } } }
为此,我实际上建议使用reflection。 在DbContext的构造函数中,您可以将属性设置为函数指针:
method = this.GetType().GetMethod("Set", new Type[0]).MakeGenericMethod(typeof(UserImplementation));
然后,您可以使用以下方法调用它:
method.Invoke(this, new object[0]);
这应该返回一个DbSet
类型的对象,然后可以调用.Cast <>()方法。
更换
nonGeneric.Cast();
通过
Enumerable.Cast(nonGeneric);
好吧,我对entity framework一无所知,但从查看文档
https://msdn.microsoft.com/en-us/library/gg696521%28v=vs.103%29.aspx
DbSet item = DbContext.Set ;
实际上你的代码与此相同:
DbSet nonGeneric = context.Set ();
并得到一个IUser
DbSet nonGeneric = context.Set();
或者可能
上述就是C#学习教程:DbSet.Cast ()错误:无法从非genericsDbSet为“实体”类型的对象创建DbSet分享的全部内容,如果对大家有所用处且需要了解更多关于C#学习教程,希望大家多多关注—计算机技术网(www.ctvol.com)!
var generic = nonGeneric.Cast>();
本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。
ctvol管理联系方式QQ:251552304
本文章地址:https://www.ctvol.com/cdevelopment/1039589.html