简体   繁体   English

实体框架核心:DbContext 不链接实体

[英]Entity Framework Core : DbContext not linking entities

I'm trying to use ASP.NET Core 2.2.0 with Entity Framework Core and I'm facing a bit of troubles.我正在尝试将 ASP.NET Core 2.2.0 与 Entity Framework Core 一起使用,但遇到了一些麻烦。

I want to display a list of pictures of different celestial objects I took (nebula, galaxies, etc...).我想显示我拍摄的不同天体(星云、星系等)的照片列表。

The data should look like this:数据应如下所示:

在此处输入图片说明

I created my entities, made the migration, and everything seemed to work great.我创建了我的实体,进行了迁移,一切似乎都运行良好。 I inserted a few data manually so I could check if the insert was ok.我手动插入了一些数据,以便检查插入是否正常。

CelestialObjectType nebuleuse = new CelestialObjectType { Name = "Nébuleuse", Definition = "Nuage interstellaire de gaz et de poussière" };
CelestialObjectType galaxie = new CelestialObjectType { Name = "Galaxie", Definition = "Vaste ensemble d'étoiles et de matière interstellaire dont la cohésion est assurée par la gravitation" };

context.CelestialObjectTypes.Add(nebuleuse);
context.CelestialObjectTypes.Add(galaxie);
 
CelestialCatalog messier = new CelestialCatalog { Name = "Messier" };
CelestialCatalog ngc = new CelestialCatalog { Name = "NGC" };
CelestialCatalog ugc = new CelestialCatalog { Name = "UGC" };

context.CelestialCatalogs.Add(messier);
context.CelestialCatalogs.Add(ngc);
context.CelestialCatalogs.Add(ugc);

CelestialObject m42 = new CelestialObject
        {
            Name = "M42 - Grande nébuleuse d'orion",
            CelestialObjectType = nebuleuse,
            DiscoveryDate = new DateTime(1610, 11, 26)
        };
CelestialObject m81 = new CelestialObject
        {
            Name = "M81 - Galaxie de Bode",
            CelestialObjectType = galaxie,
            DiscoveryDate = new DateTime(1774, 12, 31),
        };
CelestialObject m82 = new CelestialObject
        {
            Name = "M82 - Galaxie du cigare",
            CelestialObjectType = galaxie,
            DiscoveryDate = new DateTime(1774, 12, 31),
        };

context.CelestialObjects.Add(m42);
context.CelestialObjects.Add(m81);
context.CelestialObjects.Add(m82);

CelestialObjectCatalog messier42 = new CelestialObjectCatalog { CelestialCatalog = messier, CelestialObject = m42, Rank=42 };
CelestialObjectCatalog ngc1976 = new CelestialObjectCatalog { CelestialCatalog = ngc, CelestialObject = m42, Rank=1976 };

CelestialObjectCatalog messier81 = new CelestialObjectCatalog { CelestialCatalog = messier, CelestialObject = m81, Rank = 81 };
CelestialObjectCatalog ngc3031 = new CelestialObjectCatalog { CelestialCatalog = ngc, CelestialObject = m81, Rank = 3031 };
CelestialObjectCatalog ugc5318 = new CelestialObjectCatalog { CelestialCatalog = ugc, CelestialObject = m81, Rank = 5318 };

CelestialObjectCatalog messier82 = new CelestialObjectCatalog { CelestialCatalog = messier, CelestialObject = m82, Rank = 82 };
CelestialObjectCatalog ngc3024 = new CelestialObjectCatalog { CelestialCatalog = ngc, CelestialObject = m82, Rank = 3034 };
CelestialObjectCatalog ugc5322 = new CelestialObjectCatalog { CelestialCatalog = ugc, CelestialObject = m82, Rank = 5322 };

context.Add<CelestialObjectCatalog>(messier42);
context.Add<CelestialObjectCatalog>(ngc1976);

context.Add<CelestialObjectCatalog>(messier81);
context.Add<CelestialObjectCatalog>(ngc3031);
context.Add<CelestialObjectCatalog>(ugc5318);

context.Add<CelestialObjectCatalog>(messier82);
context.Add<CelestialObjectCatalog>(ngc3024);
context.Add<CelestialObjectCatalog>(ugc5322);

Picture m42Picture = new Picture
        {
            Date = new DateTime(2019, 12, 26),
            Path = "~/images/Ciel profond/M42 - Nébuleuse d'Orion.jpg",
            SingleExposureTime = new TimeSpan(0, 0, 20),
            RawNumber = 14,
            DarksNumber = 7,
            OffsetsNumber = 8
        };

Picture m8182Picture = new Picture
        {
            Date = new DateTime(2020, 02, 24),
            Path = "~/images/Ciel profond/M81-M82-Galaxies.jpeg",
            SingleExposureTime = new TimeSpan(0, 0, 30),
            RawNumber = 46,
            DarksNumber = 12,
            OffsetsNumber = 15
        };

context.Pictures.Add(m42Picture);
context.Pictures.Add(m8182Picture);

CelestialObjectPicture m42ObjectPicture = new CelestialObjectPicture { CelestialObject = m42, Picture = m42Picture };
CelestialObjectPicture m81ObjectPicture = new CelestialObjectPicture { CelestialObject = m81, Picture = m8182Picture };
CelestialObjectPicture m82ObjectPicture = new CelestialObjectPicture { CelestialObject = m82, Picture = m8182Picture };

context.Add<CelestialObjectPicture>(m42ObjectPicture);
context.Add<CelestialObjectPicture>(m81ObjectPicture);
context.Add<CelestialObjectPicture>(m82ObjectPicture);

context.SaveChanges();

Problem starts here: when I load the context from the database, entities seem not to be linked.问题从这里开始:当我从数据库加载上下文时,实体似乎没有链接。 For instance, Pictures have no references to the link entity CelestialObjectPictures :例如, Pictures没有对链接实体CelestialObjectPictures引用:

铈

But if I decide to check the CelestialObjectPictures entity, it does contains the values:但是,如果我决定检查CelestialObjectPictures实体,它确实包含以下值:

在此处输入图片说明

And if I then go back and check the Picture entity (no code run, I'm still in the same breakpoint), the CelestialObjectPictures appeared.如果我再回去检查Picture实体(没有运行代码,我仍然在同一个断点中),就会出现CelestialObjectPictures

在此处输入图片说明

The same pattern appears in all linked entities, which mean, before I manually check:相同的模式出现在所有链接的实体中,这意味着,在我手动检查之前:

  • The CelestialObject entities have no link to CelestialObjectType (null reference), nor CelestialObjectPictures and CelestialObjectCatalogs (empty lists) CelestialObject实体没有指向CelestialObjectType (空引用)的链接,也没有CelestialObjectPicturesCelestialObjectCatalogs (空列表)
  • The CelestialCatalog entities have no link to CelestialCatalogEntities (empty list) CelestialCatalog实体没有到CelestialCatalogEntities链接(空列表)
  • etc...等等...

Here is my DbContext and entities classes, please note that I tried having a DbContext with:这是我的DbContext和实体类,请注意,我尝试使用DbContext

  • Just a DbSet<Pictures> (the top object I do use in the razor page)只是一个DbSet<Pictures> (我在剃刀页面中使用的顶部对象)
  • Both a DbSet<Pictures> and a DbSet<CelestialObject> DbSet<Pictures>DbSet<CelestialObject>
  • A DbSet for each entity (the one I currently use)每个实体的 DbSet(我目前使用的那个)

Code:代码:

public class AstroWebSiteDbContext : DbContext
{
        public DbSet<CelestialObjectPicture> CelestialObjectPictures { get; set; }
        public DbSet<CelestialObjectCatalog> CelestialObjectCatalogs { get; set; }
        public DbSet<CelestialObjectType> CelestialObjectTypes { get; set; }

        public DbSet<CelestialCatalog> CelestialCatalogs { get; set; }
        public DbSet<CelestialObject> CelestialObjects { get; set; } 
        public DbSet<Picture> Pictures { get; set; }

        public AstroWebSiteDbContext(DbContextOptions<AstroWebSiteDbContext> options) : base(options)
        {
        }

        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            modelBuilder.Entity<CelestialObjectPicture>().
                HasKey(x => new { x.CelestialObjectId, x.PictureId });

            modelBuilder.Entity<CelestialObjectPicture>().
                HasOne(cop => cop.Picture).
                WithMany(pic => pic.CelestialObjectPictures).
                HasForeignKey(cop => cop.PictureId);

            modelBuilder.Entity<CelestialObjectPicture>().
                HasOne(cop => cop.CelestialObject).
                WithMany(co => co.CelestialObjectPictures).
                HasForeignKey(cop => cop.CelestialObjectId);

            modelBuilder.Entity<CelestialObjectCatalog>().
                HasKey(x => new { x.CelestialObjectId, x.CelestialCatalogId });

            modelBuilder.Entity<CelestialObjectCatalog>().
                HasOne(coc => coc.CelestialCatalog).
                WithMany(cc => cc.CelestialObjectCatalogs).
                HasForeignKey(coc => coc.CelestialCatalogId);

            modelBuilder.Entity<CelestialObjectCatalog>().
                HasOne(coc => coc.CelestialObject).
                WithMany(co => co.CelestialObjectCatalogs).
                HasForeignKey(coc => coc.CelestialObjectId);

            base.OnModelCreating(modelBuilder);
        }
}

public class CelestialObjectPicture
{
    [Key]
    public int CelestialObjectId { get; set; }
    [Key]
    public int PictureId { get; set; }

    public CelestialObject CelestialObject { get; set; }
    public Picture Picture { get; set; }
}

public class CelestialObjectCatalog
{
    [Key]
    public int CelestialObjectId { get; set; }
    public CelestialObject CelestialObject { get; set; }

    [Key]
    public int CelestialCatalogId { get; set; }
    public CelestialCatalog CelestialCatalog { get; set; }

    public int Rank { get; set; }
}

public class CelestialObject
{
    [Key]
    public int CelestialObjectId { get; set; }

    public string Name { get; set; }

    public CelestialObjectType CelestialObjectType { get; set; }
    public DateTime DiscoveryDate { get; set; }

    public List<CelestialObjectPicture> CelestialObjectPictures { get; set; } = new List<CelestialObjectPicture>();

    public List<CelestialObjectCatalog> CelestialObjectCatalogs { get; set; } = new List<CelestialObjectCatalog>();
}

public class CelestialCatalog
{
    [Key]
    public int CelestialCatalogId { get; set; }

    public string Name { get; set; }

    public List<CelestialObjectCatalog> CelestialObjectCatalogs { get; set; } = new List<CelestialObjectCatalog>();
}

I'm pretty sure I'm missing something obvious, but sadly, I couldn't find anything related to this problem.我很确定我遗漏了一些明显的东西,但遗憾的是,我找不到与此问题相关的任何内容。 Any help would be appreciated任何帮助,将不胜感激

You've effectively executed the following from within the debugger;您已经在调试器中有效地执行了以下操作;

context.Pictures.ToList(); // => select * from Pictures;
context.CelestialObjectPictures.ToList(); // => select * from CelestialObjectPictures;
context.Pictures.ToList(); // => select * from Pictures;

Each enumeration of each DbSet will load that list of objects into the change tracker.每个 DbSet 的每个枚举都会将该对象列表加载到更改跟踪器中。 Any other known objects already in the change tracker will be linked together.更改跟踪器中已有的任何其他已知对象都将链接在一起。 Databases can be huge, you rarely want to load everything.数据库可能很大,您很少想加载所有内容。

If you want to load everything at once, you should run your own query to materialise the data objects you are interested in. Including any additional foreign keys that you would also like to load at the same time;如果您想一次加载所有内容,您应该运行您自己的查询来具体化您感兴趣的数据对象。包括您还想同时加载的任何其他外键;

var objects = await context.CelestialObjects
    .Include(o => o.CelestialObjectsPictures)
        .ThenInclude(c => c.Pictures)
    .ToListAsync();

If you don't include it in your query, it won't be loaded into memory.如果您不将其包含在查询中,则不会将其加载到内存中。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM