using (var context = new BloggingContext())
{
var blogs = context.Blogs
.Include(blog => blog.Posts)
.ThenInclude(post => post.Author)
.ThenInclude(author => author.Photo)
.Select(Blogs => new BlogsItem{
Name = Blogs.Posts.Author.Name
});
}
假设 Blogs Posts Author为1对1关系
Name = Blogs.Posts.Author.Name 如果Blogs.Posts 为空 或者Blogs.Posts.Author为空会报错,这种如何处理呢?
Translation:
Assume that Blogs Posts Author is a one-to-one relationship
Name = Blogs.Posts.Author.Name If Blogs.Posts is empty or Blogs.Posts.Author is empty, it will report an error. How do I handle this?
@luy710 can you please provide a full repro, including a model and version numbers of EF Core components you are using?
@divega
thank you very much.非常感谢您能回复我所遇到的问题。
.Net Framework4.7.2 、EF Core 2.2.4.0
实体
```
public partial class Blogs
{
public string Id { get; set; }
public Posts Posts{ get; set; }
}
public partial class Posts
{
public string Id { get; set; }
public string BlogsId { get; set; }
public Author Author{ get; set; }
}
public partial class Author
{
public string Id { get; set; }
public string PostsId { get; set; }
public string Name{ get; set; }
}
public partial class BlogsItem
{
public string Name{ get; set; }
}
```
builder.HasOne(p => p.Blogs )
.WithOne(p=>p.Posts)
.HasForeignKey<Blogs >(b => b.Id)
.HasPrincipalKey<Posts>(b => b.BlogsId );
builder.HasOne(p => p.Posts)
.WithOne(p=>p.Author)
.HasForeignKey<Posts>(b => b.Id)
.HasPrincipalKey<Author>(b => b.PostsId );
数据:
Blogs :
Id
1
2
3
Posts:
Id | BlogsId
P1 1
P2 2
Author:
Id | PostsId
A1 P1
查询:
using (var context = new BloggingContext())
{
var blogs = context.Blogs.Where(p=>p.Id == 3)
.Include(blog => blog.Posts)
.ThenInclude(post => post.Author)
.ThenInclude(author => author.Photo)
.Select(Blogs => new BlogsItem{
Name = Blogs.Posts.Author.Name
});
}
@luy710 - I tried to use above snippets to put together a repro but I am unable to see any failure.
There were also several issues in the snippets which makes it not compile at all. After fixing for those errors, it still did not reproduce for me. Here is the repro code I used. Please modify it to demonstrate the issue you are seeing.
```C#
using System;
using System.Linq;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging;
namespace EFSampleApp
{
public class Program
{
public static void Main(string[] args)
{
using (var db = new MyContext())
{
// Recreate database
db.Database.EnsureDeleted();
db.Database.EnsureCreated();
// Seed database
db.AddRange(new Blogs
{
Id = "1",
Posts = new Posts { Id = "P1", Author = new Author { Id = "A1", Name = "A" } }
},
new Blogs
{
Id = "2",
Posts = new Posts { Id = "P2"}
},
new Blogs { Id = "3" });
db.SaveChanges();
}
using (var db = new MyContext())
{
// Run queries
var blogs = db.Blogs.Where(p => p.Id == "3")
.Include(blog => blog.Posts)
.ThenInclude(post => post.Author)
//.ThenInclude(author => author.Photo)
.Select(Blogs => new BlogsItem
{
Name = Blogs.Posts.Author.Name
}).ToList();
}
Console.WriteLine("Program finished.");
}
}
public class MyContext : DbContext
{
private static ILoggerFactory LoggerFactory => new LoggerFactory().AddConsole(LogLevel.Trace);
// Declare DBSets
public DbSet<Blogs> Blogs { get; set; }
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
// Select 1 provider
optionsBuilder
.UseSqlServer(@"Server=(localdb)\mssqllocaldb;Database=_ModelApp;Trusted_Connection=True;Connect Timeout=5;ConnectRetryCount=0")
//.UseSqlite("filename=_modelApp.db")
//.UseInMemoryDatabase(databaseName: "_modelApp")
.EnableSensitiveDataLogging()
.UseLoggerFactory(LoggerFactory);
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
// Configure model
}
}
public partial class Blogs
{
public string Id { get; set; }
public Posts Posts { get; set; }
}
public partial class Posts
{
public string Id { get; set; }
public string BlogsId { get; set; }
public Author Author { get; set; }
}
public partial class Author
{
public string Id { get; set; }
public string PostsId { get; set; }
public string Name { get; set; }
}
public partial class BlogsItem
{
public string Name { get; set; }
}
}
```
@smitpatel
非常感谢您
我一直以为是select里面由于Posts为空导致报错(可为空的对象必须具有一个值。)
我按照您的代码调试了下,完全没有问题
最终发现我犯了一个低级错误
public partial class Author
{
public string Id { get; set; }
public string PostsId { get; set; }
public int Name { get; set; }
}
public partial class BlogsItem
{
public int Name { get; set; }
}
由于是int所以不能将null赋值给 BlogsItem Name
@divega @smitpatel 非常感谢两位帮助我解决问题
@luy710 you are welcome!
Most helpful comment
@luy710 - I tried to use above snippets to put together a repro but I am unable to see any failure.
There were also several issues in the snippets which makes it not compile at all. After fixing for those errors, it still did not reproduce for me. Here is the repro code I used. Please modify it to demonstrate the issue you are seeing.
```C#
using System;
using System.Linq;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging;
namespace EFSampleApp
{
public class Program
{
public static void Main(string[] args)
{
using (var db = new MyContext())
{
// Recreate database
db.Database.EnsureDeleted();
db.Database.EnsureCreated();
}
```