gpt4 book ai didi

c# - Entity Framework Multi-Tenancy 共享数据架构 : single column, 多个外键

转载 作者:太空狗 更新时间:2023-10-29 18:36:05 24 4
gpt4 key购买 nike

我有以下数据结构:

//property Notification
abstract class BindableBase { }
//base class for all tenant-scoped objects
abstract class TenantModelBase : BindableBase
{
int TenantId;
}

abstract class Order : TenantModelBase
{
Customer Customer; //works: mapped using TenantId and CustomerId
Product Product; //again, works with TenantId and ProductId
string ProductId;
string CustomerId;
}
class Customer: TenantModelBase
{
string CustomerId;
}

class Product : TenantModelBase
{
string ProductId;
}

class SpecialOrder : Order
{
OtherClass OtherClass; //this fails!, see below
string OtherClassId;
}
class SuperSpecialOrder : SpecialOrder { }

class OtherClass : TenantModelBase
{
string OtherClassId;
}

我收到以下错误:

The foreign key component 'TenantId' is not a declared property on type 'SpecialOrder'. Verify that it has not been explicitly excluded from the model and that it is a valid primitive property.

使用 Fluent Api 配置时出现错误:

        config.HasRequired(p => p.OtherClass)
.WithMany(oc => oc.SpecialOrders)
.HasForeignKey(p => new { p.TenantId, p.OtherClassId});

没有 SpecialOrder 中的 OtherClass 引用,我可以毫无问题地自由创建对象(包括 SpecialOrderSuperSpecialOrder 等).

有人知道发生了什么事吗?我迷路了:(

编辑我在其他问题中看到人们从表中删除了 TenantId,这不是一个选项,因为主键在租户之间不是唯一的,我们希望保留共享数据架构。

我知道解决方法是在 SpecialOrder 类中有第二个 TenantId,但这对我来说似乎不合逻辑。

最佳答案

您是否正在尝试进行 TPT,其中有一个单独的订单/租户表?如果是这样,我认为其他发帖者是正确的,EF 中存在错误。

如果客户/产品是您基于的映射类,这可能适合您。

当我创建您的数据库时发生了什么事,它试图映射抽象 Order 类。

通过添加:

modelBuilder.Ignore<Order>();

由于 MapInheritedProperties,构建器保留了映射的属性,但没有创建表以便正确创建所有 FK。

我假设您想像上面的相关帖子一样为每个类使用单独的表格,而不是映射您的抽象表格。

整个模型:

 public abstract class BindableBase { }
//base class for all tenant-scoped objects
public abstract class TenantModelBase : BindableBase
{
[Key]
public virtual int TenantId { get; set; }
}

public abstract class Order : TenantModelBase
{
public Customer Customer { get; set; } //works: mapped using TenantId and CustomerId
public Product Product { get; set; } //again, works with TenantId and ProductId
public string ProductId { get; set; }
public string CustomerId { get; set; }
}
public class Customer : TenantModelBase
{
[Key]
public string CustomerId { get; set; }
}

public class Product : TenantModelBase
{
[Key]
public string ProductId { get; set; }
}

public class SpecialOrder : Order
{
[Key]
public int SpecialOrderId { get; set; }
public OtherClass OtherClass { get; set; } //this fails!, see below
public string OtherClassId { get; set; }
}
public class SuperSpecialOrder : SpecialOrder { }

public class OtherClass : TenantModelBase
{
public string OtherClassId { get; set; }
public ICollection<SpecialOrder> SpecialOrders { get; set; }
}



public class Model : DbContext
{
public DbSet<Customer> Customers { get; set; }
public DbSet<Product> Products { get; set; }
public DbSet<SpecialOrder> SpecialOrders { get; set; }
public DbSet<SuperSpecialOrder> SuperSpecialOrders { get; set; }

public DbSet<OtherClass> OtherClasses { get; set; }

protected override void OnModelCreating( DbModelBuilder modelBuilder )
{
modelBuilder.Entity<OtherClass>()
.HasKey( k => new { k.TenantId, k.OtherClassId } );

modelBuilder.Entity<Customer>()
.HasKey( k => new { k.TenantId, k.CustomerId } );

modelBuilder.Entity<Product>()
.HasKey( k => new { k.TenantId, k.ProductId } );


modelBuilder.Entity<SpecialOrder>()
.Map( m =>
{
m.MapInheritedProperties();
m.ToTable( "SpecialOrders" );
} );

modelBuilder.Entity<SpecialOrder>().HasKey( k => new { k.TenantId, k.SpecialOrderId } );

modelBuilder.Entity<SuperSpecialOrder>()
.Map( m =>
{
m.MapInheritedProperties();
m.ToTable( "SuperSpecialOrders" );
} )
.HasKey( k => new { k.TenantId, k.SpecialOrderId } );

modelBuilder.Entity<SpecialOrder>()
.HasRequired( p => p.OtherClass )
.WithMany( o => o.SpecialOrders )
.HasForeignKey( p => new { p.TenantId, p.OtherClassId } );

modelBuilder.Entity<Order>()
.HasRequired( o => o.Customer )
.WithMany()
.HasForeignKey( k => new { k.TenantId, k.CustomerId } );

modelBuilder.Entity<Order>()
.HasRequired( o => o.Product )
.WithMany()
.HasForeignKey( k => new { k.TenantId, k.ProductId } );

modelBuilder.Ignore<Order>();


}
}

创建的数据库: enter image description here

希望这对您有所帮助。

关于c# - Entity Framework Multi-Tenancy 共享数据架构 : single column, 多个外键,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11949742/

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