在“数据库优先”中使用相关实体的问题

问题描述 投票:0回答:1

我正在学习MVC,为此,我正在开发一个“智能论坛”。我有一个数据库,但我对实体有一些问题。我做了这个命令

 "Scaffold-DbContext "Server=(localdb)\mssqllocaldb;Database=SmartForum;Trusted_Connection=True; Microsoft.EntityFrameworkCore.SqlServer -OutputDir ModelsFromDb" ,

代码段:

modelBuilder.Entity<ArgomentiPerArea>(entity =>
            {
                entity.HasKey(e => e.ArgomentoId);

                entity.Property(e => e.ArgomentoId).HasColumnName("argomentoId");

                entity.Property(e => e.Archiviato).HasColumnName("archiviato");

                entity.Property(e => e.AreaId).HasColumnName("areaId");

                entity.Property(e => e.ModeratoreId).HasColumnName("moderatoreId");

                entity.Property(e => e.NomeArgomento).HasColumnName("nome_argomento");

                entity.Property(e => e.NumeroRigaPerArea).HasColumnName("numero_riga_per_area");

                entity.Property(e => e.TestoPerArgomento).HasColumnName("testo_per_argomento");

                entity.HasOne(d => d.Area)
                    .WithMany(p => p.ArgomentiPerArea)
                    .HasForeignKey(d => d.AreaId)
                    .HasConstraintName("FK_ArgomentiPerArea_Aree");

                entity.HasOne(d => d.Moderatore)
                    .WithMany(p => p.ArgomentiPerArea)
                    .HasForeignKey(d => d.ModeratoreId)
                    .HasConstraintName("FK_ArgomentiPerArea_Moderatori");
            });

第二个片段:

public partial class ArgomentiPerArea
    {
        public ArgomentiPerArea()
        {
            Thread = new HashSet<Thread>();
        }
        [Key]
        public int ArgomentoId { get; set; }
        public string NomeArgomento { get; set; }
        public int? AreaId { get; set; }
        public bool? Archiviato { get; set; }
        public int? NumeroRigaPerArea { get; set; }
        public string TestoPerArgomento { get; set; }
        public int? ModeratoreId { get; set; }

        public virtual Aree Area { get; set; }
        public virtual Moderatori Moderatore { get; set; }
        public virtual ICollection<Thread> Thread { get; set; }

    }

public partial class Aree
    {
        public Aree()
        {
            ArgomentiPerArea = new HashSet<ArgomentiPerArea>();
        }
        [Key]
        public int AreaId { get; set; }
        public string NomeArea { get; set; }
        public int? NumeroRiga { get; set; }
        public int? NumeroColonna { get; set; }

        public virtual ICollection<ArgomentiPerArea> ArgomentiPerArea { get; set; }
    }

public partial class Moderatori
    {
        public Moderatori()
        {
            ArgomentiPerArea = new HashSet<ArgomentiPerArea>();
            SegnalazioniPerModeratori = new HashSet<SegnalazioniPerModeratori>();
        }
        [Key]
        public int ModeratoreId { get; set; }
        public string UsernameModeratore { get; set; }
        public string PasswordHash { get; set; }
        public string NomeCognome { get; set; }
        public bool? Archiviato { get; set; }

        public virtual ICollection<ArgomentiPerArea> ArgomentiPerArea { get; set; }
        public virtual ICollection<SegnalazioniPerModeratori> SegnalazioniPerModeratori { get; set; }
    }

当这段代码运行时

public class ArgomentiPerAreasController : Controller
    {
        private ModelsFromDb.SmartForumContext db = new ModelsFromDb.SmartForumContext();

        // GET: ArgomentiPerAreas
        public ActionResult Index()
        {
            var argomentiPerAreas = db.ArgomentiPerArea.Include(a => a.Area).Include(a => a.Moderatore);            

            string msg = "m";
            return View(argomentiPerAreas.ToList());
        }

.............
.............}

我在视图中检查并且“moderatore”和“area”具有空值。我不明白但我知道数据库第一和MVC表面上。我希望有一些建议。

c# entity-framework ef-database-first
1个回答
1
投票

这可能是由于您的Argomenti *和主持人/区域之间的循环引用。区域将一个集合保存回Argomenti *,因此当MVC序列化根实体(Argomenti)时,它会遇到区域,然后遍历该区域,Argomenti *的集合,并且循环进行。它纾困并且不会尝试序列化循环依赖。

通常,使用EF和视图最好的做法是不尝试将实体发送到视图。而是创建一个POCO(普通旧C#对象)视图模型发送到视图。此视图模型仅包含视图所需的字段,并且您的EF查询使用.Select()来填充该视图模型。这避免了整个循环引用问题,并且无需故意加载(.Include())或延迟加载的性能风险。

例如:如果我想要一个Argumenti列表,我想显示每个Area和Moderator作为其中的一部分:

[Serializable]
public class ArgumentiViewModel
{
    public string NomeArgomento { get; set; }
    public bool? Archiviato { get; set; }
    public int? NumeroRigaPerArea { get; set; }
    public string TestoPerArgomento { get; set; }
    public string NomeArea { get; set; } // From Area
    public string NomeCognome { get; set; } // From Moderator
}

然后,当我想将此返回到视图时:

var argomentiViewModels = db.ArgomentiPerArea
    .Select(x => new ArgomentiViewModel
    {
        NomeArgomento = x.NomeArgomento,
        Archiviato - x.Archiviato,
        NumeroRigaPerArea = x.NumeroRigaPerArea,
        TestoPerArgomento = x.TestoPerArgomento,
        NomeArea = x.Area.NomeArea, // From Area
        NomeCognome = x.Moderatori.NomeCognome // From Moderator
    }).ToList();

string msg = "m";
return View(argomentiViewModels);

我总结了几个很好的理由,为什么代码不应该返回实体到视图qazxsw poi。

© www.soinside.com 2019 - 2024. All rights reserved.