Проблема с использованием связанных сущностей в «БД-сначала» - PullRequest
0 голосов
/ 07 марта 2019

Я изучаю 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 поверхностно.Я надеюсь на некоторые предложения.

1 Ответ

1 голос
/ 08 марта 2019

Вероятно, это связано с круговыми ссылками между вашим Argomenti * и модератором / областью. Область удерживает коллекцию обратно в Argomenti *, поэтому, когда MVC начинает сериализовать корневую сущность (Argomenti), она попадает в Area, затем перебирает область, собирает Argomenti *, и цикл продолжается. Выручает и не пытается сериализовать циклические зависимости.

Обычно лучше всего использовать EF и представления , а не , чтобы попытаться отправить объекты в представление. Вместо этого создайте модель представления POCO (обычный старый объект C #) для отправки в представление. Эта модель представления содержит только поля, необходимые для представления, и ваш запрос EF использует .Select() для заполнения этой модели представления. Это позволяет избежать всей проблемы с циклическими ссылками и исключает необходимость преднамеренной активной загрузки (.Include()) или риска производительности из-за отложенной загрузки.

Например: если мне нужен список Argumenti, и я хочу отобразить каждую область и модератора как часть этого:

[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);

Я суммировал пару веских причин, по которым код не должен возвращать сущности в представление здесь .

...