gpt4 book ai didi

c# - DbSet.Cast() 错误 : Cannot create a DbSet from a non-generic DbSet for objects of type 'Entity'

转载 作者:太空狗 更新时间:2023-10-29 21:01:50 25 4
gpt4 key购买 nike

版本信息:

我正在使用 C# 4.5、Entity Framework 6.0 和 MEF。

代码和单元测试

我创建了一个测试项目来解释这个问题: https://skydrive.live.com/redir?resid=E3C97EC293A34048!2234

请打开 UnitTest 项目并尝试运行 TestIfItWorks() 单元测试。

问题

我想将非通用 DbSet 转换为其通用版本,但出现以下异常:InvalidCastException: Cannot create a DbSet<IUser> from a non-generic DbSet for objects of type 'User' :

var nonGeneric = context.Set(typeof(User));
var generic = nonGeneric.Cast<IUser>(); //Exception in here

User 类正在实现 IUser,因此您会认为转换应该不是问题,除非 DbSet 代码仅限于具体类(我希望不会,否则我需要围绕非通用 DbSet 创建一个包装器以将其转换为通用 DbSet 或找到当前 DbSet 实现的替代方案)。

如果你想知道为什么我要使用接口(interface),即使它们目前不受 Microsoft 支持,我会给你一些解释(希望这会过滤掉说“不要那样做”而不是提供解决方案的响应):

我正在使用 MEF 和 EntityFramework 创建一个松散耦合的数据层引擎,通过它我可以为每个项目提供实体(及其相应的配置)。我一直在广泛使用接口(interface)来定义引擎。使用 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<User>();

//Failed Attempt# 2: But the good thing is that we have access to IUser and its exports
//then lets get a DbSet<IUser> instead
var failedAttempt2 = dbContext.Set<IUser>();
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 EntityTypeConfiguration<IUser>at 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<IUser>().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<IUser>();
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<IUser>();
}
catch (InvalidCastException ex)
{
//Cannot create a DbSet<IUser> from a non-generic DbSet for objects of type 'User'.
throw;
}
}
}

最佳答案

为此,我实际上建议使用反射。在 DbContext 的构造函数中,您可以为函数指针设置一个属性:

method = this.GetType().GetMethod("Set", new Type[0]).MakeGenericMethod(typeof(UserImplementation));

然后您可以使用以下方式调用它:

method.Invoke(this, new object[0]);

这应该返回一个 DbSet<UserImplementation> 类型的对象然后可以调用 .Cast<>() 方法。

关于c# - DbSet.Cast<TEntity>() 错误 : Cannot create a DbSet<IEntity> from a non-generic DbSet for objects of type 'Entity' ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19609981/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com