gpt4 book ai didi

c# - 没有外键的EF Core关系

转载 作者:行者123 更新时间:2023-12-03 13:40:36 29 4
gpt4 key购买 nike

如何在不声明外键的情况下设置导航属性?

我有两个表( segmentcategory ),它们可以使用 2 列(来源/目的地)连接,但它们不满足外键约束,因为它们可以具有另一个表中不存在的值(所以它不是关于空或非空)

分割

Id   Date       OriginId  DestinationId
---------------------------------------
1 2020-01-10 1 2
2 2020-01-18 2 1
2 2020-02-05 1 3
4 2020-04-11 3 3

分类
Id  OriginId   DestinationId  Category
-----------------------------------------
1 1 2 Primary
2 2 1 Secondary
2 2 3 Primary

我想知道每个 Segment类别。但并非每个段都存在于 Category 中所以某些分割市场将没有类别。

此 SQL 有效:
SELECT 
s.*, c.name
FROM
Segment s
LEFT OUTER JOIN
Category c ON c.originId = s.originId AND c.destinationId = s.destinationId

这个 LINQ 也有效:
from s in Segment
join c in Category on new { s.OriginId, s.DestinationId } equals new { c.OriginId, c.DestinationId } into grouping
from c in grouping.DefaultIfEmpty()
select new { s, c };

但是要使用导航,我得到的最接近的是:我分别在每个类上添加了一个属性,并使用 fluent api 在上下文中设置关系
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Segment>()
.HasOne(segment => segment.Category)
.WithMany(category => category.Segments)
.HasForeignKey(segment => new { segment.OriginId, segment.DestinationId })
.HasPrincipalKey(category => new { category.OriginId, category.DestinationId })
.IsRequired(false);
}

// then I can do
var query = Segments.Include(o => o.Category).ToList();

这用于检索数据库中已存在的记录。

但是要向类别中不存在 originId 和 destinationId 的 Segment 插入新记录,它会提示 originId 和 destinationId 不符合外键约束。没关系,因为它们不存在于另一个表中。

它们实际上不是外键,只是用于加入它们的列,但我不知道如何使用导航属性 + Fluent Api 来设置它。

最佳答案

第一的:

    [System.Diagnostics.CodeAnalysis.SuppressMessage("Usage", "EF1001:Internal EF Core API usage.", Justification = "<挂起>")]
public class MigrationsModelDifferWithoutForeignKey : MigrationsModelDiffer
{
public MigrationsModelDifferWithoutForeignKey
([NotNull] IRelationalTypeMappingSource typeMappingSource,
[NotNull] IMigrationsAnnotationProvider migrationsAnnotations,
[NotNull] IChangeDetector changeDetector,
[NotNull] IUpdateAdapterFactory updateAdapterFactory,
[NotNull] CommandBatchPreparerDependencies commandBatchPreparerDependencies)
: base(typeMappingSource, migrationsAnnotations, changeDetector, updateAdapterFactory, commandBatchPreparerDependencies)
{
}

public override IReadOnlyList<MigrationOperation> GetDifferences(IModel source, IModel target)
{
var operations = base.GetDifferences(source, target)
.Where(op => !(op is AddForeignKeyOperation))
.Where(op => !(op is DropForeignKeyOperation))
.ToList();

foreach (var operation in operations.OfType<CreateTableOperation>())
operation.ForeignKeys?.Clear();

return operations;
}
}
如何使用:
services.AddDbContext<MyDbContext>(options =>
{
options.UseSqlServer(Default);
options.ReplaceService<IMigrationsModelDiffer, MigrationsModelDifferWithoutForeignKey>();
});

关于c# - 没有外键的EF Core关系,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61062549/

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