- 问题**-我需要在两个具有属性"SourceTransactionId"的实体之间创建某种类型的Map,其中任何一个实体都可以先添加到数据库中,然后再添加另一个,但仍然可以进行如下查询。
- 我想要的**:向发件人或收件人显示转账(取决于谁请求查看其转账)及其关联的StripePayment数据:
var transfers = _dbContext.StripeTransfers.Select(p => new {
TransferAmount = p.StripePayment.Amount,
TransferDate = p.DateCreated,
Sender = p.StripePayment.Sender.UserName,
Receiver = p.StripePayment.Receiver.UserName
}).Where(p => p.StripePayment.Sender.Id == userId || p.StripePayment.Receiver.Id == userId)
.ToListAsync();
- 要求**-我不知道将首先创建哪个实体,因为StripeTransfer是从一个webhook创建的,而该webhook可能在我创建StripePayment实体之前收到,因此任何一行都应该能够在另一行之前添加。
下面是我的代码:
public class StripePayment
{
// primary key
public int Id { get; set; }
public string SourceTransactionId { get; set; }
public StripeTransfer StripeTransfer { get; set; }
public int Amount { get; set; }
public int SenderId { get; set; }
public User Sender { get; set; }
public int ReceiverId { get; set; }
public User Receiver { get; set; }
}
public class StripeTransfer
{
// primary key
public int Id { get; set; }
public string SourceTransactionId { get; set; }
public StripePayment StripePayment { get; set; }
public DateTime DateCreated { get; set; }
}
- 我尝试的操作**-我尝试添加外键约束,但这不允许我在创建StripePayment之前添加StripeTransfer。
modelBuilder.Entity<StripePayment>()
.HasOne<StripeTransfer>(t => t.StripeTransfer)
.WithOne(t => t.StripePayment)
.HasPrincipalKey<StripePayment>(p => p.SourceTransactionId)
.HasForeignKey<StripeTransfer>(t => t.SourceTransactionId)
.IsRequired(false);
尝试在StripePayment之前添加StripeTransfer时收到错误:
INSERT语句与FOREIGN KEY约束"FK_StripeTransfers_StripePayments_SourceTransactionId"冲突。冲突发生在数据库"yogabandy-database-dev"、表"dbo.StripePayments"、列"LatestChargeId"中。\n语句已终止。
2条答案
按热度按时间8wigbo561#
这是一个特殊的0..1 - 0..1关系,我还没有遇到过,让我总结一下它的性质,这样我们就可以检查一下我们是否在同一页上。
在没有任何关系建模的情况下,可以通过两个连接属性上的定制
join
语句来查询实体,这可能是一个可行的解决方案。但让我们来看看EF在这里能做些什么。
在数据库中,由于两个实体可以在没有对应实体的情况下存在,因此任何实体都不能具有指向另一实体的外键。只能通过引用这两个表的联接表来强制关系。
尽管如此,好消息是EF的配置API的表达能力足以对此进行建模。
类(省略用户字段):
交叉点类别:
是的,它只是一个
string
属性。Map配置:
一些亮点:
SourceTransactionId
)的关系。它通过HasForeignKey
语句识别这些键。PaymentTransfer.SourceTransactionId
是两个独立(主体)实体的主键和外键(对我来说,一个字段中有这么多函数是这个问题有趣的部分)。SourceTransactionId
字段都将获得唯一索引。当首先使用数据库时,请确保创建这些索引。现在,退一步,让我们评估一下选项。
join
语句就足够了,但是手工编码的连接很繁琐而且容易出错,不过,当它隐藏在一些可重用的方法中时,它可能是最好的选择。p.PaymentTransfer.StripePayment.Amount
等)进行查询。fnvucqvd2#
请尝试此操作。您只需更改 HasPrincipalKey 和 HasForeignKey 中的泛型类型。