gpt4 book ai didi

c# - LINQ 到实体 : perform joins on many-to-many relationships (code first)

转载 作者:行者123 更新时间:2023-12-05 06:29:45 24 4
gpt4 key购买 nike

我有以下模型:

[Table("Experiments")]
public class Experiment
{
...

public virtual ICollection<ExperimentType> ExperimentTypes { get; set; }

public Experiment()
{
ExperimentTypes = new List<ExperimentType>();
}
}

[Table("ExperimentTypes")]
public class ExperimentType
{
...

public virtual ICollection<Experiment> Experiments { get; set; }

public ExperimentType()
{
Experiments = new List<Experiments>();
}
}

DbSet 包含:

    public DbSet<Experiment> Experiments { get; set; }
public DbSet<ExperimentType> ExperimentTypes{ get; set; }

这会在 SQL 上创建一个表,称为 ExperimentExperimentTypes。

现在,我想执行 LINQ 连接,例如:

var query =
from e in database.Experiments
join eet in database.ExperimentExperimentTypes on eet.Experiment_Id equals eet.ExperimentType_Id ...

但显然 database.ExperimentExperimentTypes 在代码中无法识别。

我尝试了很多东西来告诉代码有这个表,我也尝试创建相应的 c# 类,但我没有得到任何结果。

如何实现?

最佳答案

所以你有两个表:ExperimentExperimentType .这两者之间存在多对多关系:每个 Experiment是零个或多个 ExperimentTypes 的实验;每个ExperimentType是零个或多个 Experiments 的类型.

这个多对多可以在你的类定义中看到。 virtual ICollection<...>两边表示多对多关系。

在关系数据库中,这种多对多关系是使用联结表实现的。然而,在 Entity Framework 中你很少看到联结表。它在您的数据库中,但是,您无法使用 DbContext 访问它

But how am I going to perform a join between Experiments andExperimentTypes if I can't access the junction table?

好吧,维尼熊该回到他的思考点了。你不想连接表,你想要 Experiments , 每个都有它的 ExperimentTypes .

那么为什么不直接使用 ICollection<...> 进行查询呢? ?

var experiments = myDbContext.Experiments
.Where(experiment => ...) // only if you don't want all experiments
.Select(experiment => new
{ // Select only the properties you actually plan to use
Id = experiment.Id,
Name = experiment.Name,
...

// get all or some of its ExperimentTypes
ExperimentTypes = experiment.ExperimentTypes
.Where(experimentType => ...) // only if you don't want all experiment types
.Select(experimentType => new
{
// again: select only the properties you plan to use
Id = experimentType.Id,
...
})
.ToList(),
});

Entity Framework 了解多对多,它知道为此需要与联结表进行三重连接,并将执行此三重连接。

在内部这将是一个GroupJoin,你会得到Experiments , 每个都有自己的 ExperimentTypes .您甚至可以获得还没有任何 ExperimentType 的 Experiments。

如果你真的想要 inner join ,您必须将 Experiments 与它们的 ExperimentTypes 展平。这是使用 overload of SelectMany that has a resultSelector as parameter 完成的

// flatten the Experiments with their experimentTypes
var flatInnerJoin = myDbContext.Experiments.SelectMany(experiment => experiment.ExperimentTypes,

// from each experiment and one of its experimentTypes make one new object
(experiment, experimentType) => new
{
ExperimentId = experiment.Id,
ExperimentTypeId = experimentType.Id,
...
});
})

请注意!这样您就不会获得没有 ExperimentType 的 Experiments,就像在标准内部联接中一样。

关于c# - LINQ 到实体 : perform joins on many-to-many relationships (code first),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53266879/

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