ef core 3 OwnsOne,选择失败,并带有两个表

时间:2019-07-18 09:32:00

标签: c# entity-framework

以下示例失败。

  

System.NullReferenceException:“对象引用未设置为   对象的实例。”

数据保存有效。如果我通过Include获得数据,那也可以。只有在读取数据时才会出现此错误。一张桌子一切都很好。在2.6版中,该示例可以正常工作。 有人能帮我吗? 我与Microsoft合作。 EntityFrameworkCore 3.0.0-preview6.19304.10

谢谢

using Microsoft.EntityFrameworkCore;
using System;
using System.Linq;
using System.Threading.Tasks;

namespace ConsoleApp1
{
    public class JgLogDb : DbContext
    {
        public string SqlVerbindung = @"Data Source=.\SqlExpress;Initial Catalog = JgTest; Integrated Security = True";

        public DbSet<TabTest1> TabTest1Set { set; get; }
        public DbSet<TabTest2> TabTest2Set { set; get; }

        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            modelBuilder.Entity<TabTest1>().OwnsOne(p => p.MTest);
            modelBuilder.Entity<TabTest2>().OwnsOne(p => p.MTest);

            base.OnModelCreating(modelBuilder);
        }

        protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
        {
            optionsBuilder.UseSqlServer(SqlVerbindung);
        }
    }

    public class TabTest1
    {
        public Guid Id { get; set; } = Guid.NewGuid();
        public string Feld1 { get; set; }
        public MeinTest MTest { get; set; }
    }

    public class TabTest2
    {
        public Guid Id { get; set; } = Guid.NewGuid();
        public string Fel2 { get; set; }
        public MeinTest MTest { get; set; }
    }

    [Owned]
    public class MeinTest
    {
        public string FeldTest { get; set; }
    }

    class Program
    {
        static async Task Main()
        {
            using (var db = new JgLogDb())
            {
                await db.TabTest1Set.AddAsync(new TabTest1()
                {
                    Feld1 = "Hallo",
                    MTest = new MeinTest()
                    {
                        FeldTest = "Ballo"
                    }
                });
                await db.SaveChangesAsync();
            }

            using (var db = new JgLogDb())
            {
                var liste = await db.TabTest1Set
                    .Select(s => new
                    {
                        f1 = s.Feld1,
                        f2 = s.MTest.FeldTest
                    }).ToListAsync();

                foreach (var ds in liste)
                    Console.WriteLine($"{ds.f1}  {ds.f2}");
            }

            Console.ReadLine();
        }
    }
}

2 个答案:

答案 0 :(得分:1)

您的问题可能与此EF核心问题有关:https://github.com/aspnet/EntityFrameworkCore/issues/13546

显然,EF Core中存在一个未解决的错误,如果您使用投影(.Select),它将不会自动包含拥有的实体。

解决方法是将其明确包含:.Include(x => x.MTest)

答案 1 :(得分:0)

我已修改代码以使用Sqlite,它通常比SqlServer受到更多限制:

checkcast

请注意,我的代码正在破坏数据库(通过namespace ConsoleApp1 { public class JgLogDb : DbContext { [...] protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) { optionsBuilder.UseSqlite("Data Source=test.db"); } } [...] class Program { static async Task Main() { using (var db = new JgLogDb()) { db.Database.EnsureDeleted(); db.Database.EnsureCreated(); await db.TabTest1Set.AddAsync(new TabTest1() { Feld1 = "Hallo", MTest = new MeinTest() { FeldTest = "Ballo" } }); await db.SaveChangesAsync(); } [...] } } } )并从头开始创建数据库(通过EnsureDeleted()),因此可能是您现有的EnsureCreated()数据库与模型不同

也就是说,嵌套SqlExpress对象存在类似的问题。值得一看Fluent API for .ToTable(),因为当前对拥有实体有一些限制:https://msdn.microsoft.com/en-us/magazine/mt846463.aspx