Entity framework 参照另一上下文中的实体创建新实体
我有两个项目PRJ1和PRJ2,它们使用自己的数据库DB1和DB2。每个数据库都使用EF代码优先迁移Entity framework 参照另一上下文中的实体创建新实体,entity-framework,entity-framework-migrations,Entity Framework,Entity Framework Migrations,我有两个项目PRJ1和PRJ2,它们使用自己的数据库DB1和DB2。每个数据库都使用EF代码优先迁移 PRJ1用于管理产品库存(已存在4年) PRJ2用于订单(全新项目仍在开发中) 现在我们只谈第二个项目。在我的项目中,我需要访问另一个数据库中的数据。所以我需要订购产品 以下是我到目前为止为PRJ2 注意,我定义了两个不同的上下文 // Context for accessing entities in DB1 public class DB1Context : DbContext {
- PRJ1用于管理产品库存(已存在4年)
- PRJ2用于订单(全新项目仍在开发中)
// Context for accessing entities in DB1
public class DB1Context : DbContext
{
static DB1Context()
{
Database.SetInitializer<DB1Context>(null);
}
public DbSet<Product> Products { get; set; }
}
// Context for accessing entities in DB2
public class DB2Context : DbContext
{
static DB2Context()
{
Database.SetInitializer(new MigrateDatabaseToLatestVersion<DB2Context, DAL.Migrations.Configuration>());
}
public DbSet<Anything> Anythings { get; set; }
public DbSet<Order> Orders { get; set; }
}
位于DB2Context中的该实体引用的是属于DB2Context的产品
实体
现在的问题是,只要我将这个实体添加到我的上下文DbSet
中,我就会看到有一个迁移正在等待产品。此迁移用于在我的DB2Context中创建产品。那不是我想要的。此实体已存在于DB1Context中。似乎我无法创建这个订单实体,它从其他上下文引用产品
你能证实这一点吗?我错过什么了吗?否则,最好的选择是什么 我认为使用实体框架无法做到这一点 这个问题看起来像是无SQL数据库的问题。当您有多个这样的数据库时,您必须控制所有数据库的所有CRUD。ADO无法对您执行此操作,因为您没有数据完整性 一个可能的解决方案是将CRUD放在业务逻辑层中。。或者类似的 假设您要控制一个
OrderBll
:
public class OrderBll
{
private DB1Context _DB1Context = new DB1Context();
private DB2Context _DB2Context = new DB2Context();
public List<Orders> GetOrders()
{
var orders = _DB2Context.Orders.Where(???).ToList();
var productIds = orders.Select(x => x.ProductId).Distinct().ToArray();
var products = _DB1Context.Products.Where(x => productIds.Contains(x.Id)).ToList(); // Optimize the load of all products in orders
// Set the product object in the order list
foreach( var order in orders )
{
order.Product = products.FirstOrDefault(x=>x.Id == order.ProductId);
}
return orders;
}
}
公共类OrderBll
{
私有DB1Context_DB1Context=新的DB1Context();
私有DB2Context_DB2Context=new DB2Context();
公共列表GetOrders()
{
var orders=_DB2Context.orders.Where(???).ToList();
var ProductId=orders.Select(x=>x.ProductId.Distinct().ToArray();
var products=_DB1Context.products.Where(x=>productIds.Contains(x.Id)).ToList();//优化订单中所有产品的负载
//在订单列表中设置产品对象
foreach(订单中的var订单)
{
order.Product=products.FirstOrDefault(x=>x.Id==order.ProductId);
}
退货订单;
}
}
请记住,您必须在订单
中映射产品
属性,如忽略
因此,您必须自己设置外键并执行所有约束检查
但是,如果其他人有更好的解决方案,我很高兴知道。理想情况下,这就是你应该追求的目标
是的,我可以证实。不,你没有错过任何东西。选择?有时,这可以通过将表链接到另一个数据库来解决,但这是一个脆弱的解决方案。你仍然会有迁移问题。谢谢@GertArnold的评论。我很失望,我的问题似乎没有解决办法。我一定不是第一个遇到这种情况的人。我所介绍的场景在我看来相当经典。在另一个数据库中拥有实体的导航属性一点也不经典。当然,各种数据源之间的通信是例行的,但这并不相同。通常,这是通过API(即web服务)实现的,而不是通过直接连接到多个数据库来实现的。但是,通过使用API,我们无法实现关系完整性。在我的例子中,我可以使用一个web服务从我的DB1中检索所有产品,只需在DB2中使用一个
int
,以保持对特定产品(DB1)的简单“引用”。但是这个产品可以在没有任何关系完整性约束的情况下被删除(在DB1中)。您也不能跨数据库强制执行引用完整性。至少,不受外键限制。非常有趣,谢谢。让我们看看其他人是否有其他想法/选择。
public class OrderBll
{
private DB1Context _DB1Context = new DB1Context();
private DB2Context _DB2Context = new DB2Context();
public List<Orders> GetOrders()
{
var orders = _DB2Context.Orders.Where(???).ToList();
var productIds = orders.Select(x => x.ProductId).Distinct().ToArray();
var products = _DB1Context.Products.Where(x => productIds.Contains(x.Id)).ToList(); // Optimize the load of all products in orders
// Set the product object in the order list
foreach( var order in orders )
{
order.Product = products.FirstOrDefault(x=>x.Id == order.ProductId);
}
return orders;
}
}