简体   繁体   English

.NET Core 在实体受保护且属性在洋葱架构中为私有集时,如何在多对多的相关表中保存数据?

[英]How to save data in related tables in many-to-many in .NET Core when the entities are protected and properties are private set in onion architecture?

I have the following entities:我有以下实体:

LawFAQ entity: LawFAQ实体:

namespace HW_R2.Domain.LawFAQAgg
{
        public class LawFAQ
        {
            public int Id { get; private set; }
            public string Question { get; private set; }
            public string Answer { get; private set; }
            public bool IsDeleted { get; private set; }
            public DateTime  CreationDate { get; private set; }
    
            // For n*1 relationship between LawFAQ and LawFaqLawCategory
            public List<LawFAQLawCategory> LawFAQLawCategories { get; private set; }
    
            protected LawFAQ()
            {       
            }
    
            public LawFAQ(string question, string answer)
            {
                Question = question;
                Answer = answer;
                IsDeleted = false;
                CreationDate = DateTime.Now;                                      
            }
                   
            public void Activate()
            {
                IsDeleted = false;
            }
    
            public void Remove()
            {
                IsDeleted = true;
            }
    
            public void Edit(string question, string answer)
            {
                Question = question;
                Answer = answer;
            }
        }
}
    
    

LawCategory entity: LawCategory实体:

namespace HW_R2.Domain.LawCategoryAgg
{
        public class LawCategory
        {
            public int Id { get; private set; }
            public string Title { get; private set; }
            public string ShotDesc { get; private set; }
            public string FullContDesc { get; private set; }        
            public string Img { get; private set; }
            public bool IsDeleted { get; private set; }
            public DateTime CreationDate { get; private set; }
                         
           // For n*1 relationship between LawCategory and LawFAQLawCategory
            public List<LawFAQLawCategory> LawFAQLawCategories { get; private set; }                      
    
            protected LawCategory()
            {
            }      
            
            public LawCategory(string title, string shortDesc, string fullContDesc, string img)
            {
                Title = title;
                ShotDesc = shortDesc;
                FullContDesc = fullContDesc;
                Img = img;
                IsDeleted = false;
                CreationDate = DateTime.Now;
            }                     
        }
}
     

And LawFAQLawCategory entity:LawFAQLawCategory实体:

namespace HW_R2.Domain.LawFAQLawCategoryAgg
{
    public class LawFAQLawCategory
    {
        public int LawFAQId { get; private set; }
        public LawFAQ LawFAQ { get; private set; }

        public int LawCategoryId { get; private set; }
        public LawCategory LawCategory { get; private set; }

        protected LawFAQLawCategory()
        {    
        }

        public LawFAQLawCategory(int lawFAQId,int lawCategoryId)
        {
            LawFAQId =lawFAQId;
            LawCategoryId = lawCategoryId;
        }    
    }
}

The LawFAQApplication is: LawFAQApplication是:

using HW_R2.Application.Contracts.LawFAQ;
using HW_R2.Domain.LawFAQAgg;
using System.Collections.Generic;

namespace HW_R2.Application
{
    public class LawFAQApplication:ILawFAQApplication
    {
        private readonly ILawFAQRepository _lawFAQRepository;

        public LawFAQApplication(ILawFAQRepository lawFAQRepository)
        {
            _lawFAQRepository = lawFAQRepository;
        }
            
        public void Create(Create command)
        {
             //_lawFAQRepository.Create(new LawFAQ(command.Question,command.Answer));
            _lawFAQRepository.Create(command);
        }
    }
}

And the LawFAQRepository is: LawFAQRepository是:

using HW_R2.Application.Contracts.LawFAQ;
using HW_R2.Domain.LawFAQAgg;
using HW_R2.Domain.LawFAQLawCategoryAgg;
using Microsoft.EntityFrameworkCore;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;

namespace HW_R2.Infrastracture.EFCore.Repositories
{
    public class LawFAQRepository: ILawFAQRepository
    {
        private readonly HamedWebsire_Refac2Context _context;

        public LawFAQRepository(HamedWebsire_Refac2Context context)
        {
            _context = context;
        }

        // public void Create(LawFAQ entity)
        public void Create(Create command)
        {
            var entity = new LawFAQ(command.Question, command.Answer);
             _context.LawFAQs.Add(entity);           
            
            foreach (var item in command.LawCategoryIds)
            {
                entity.LawFAQLawCategories.Add(new LawFAQLawCategory(entity.Id, item));
            }

            //PropertyEntry<LawFAQ, int> id = _context.Entry(entity).Property<int>("Id");
            Save();
        }

        public void Save()
        {
            _context.SaveChanges();
        }
    }
}

The problem I have is that on the line (in 'LawFAQRepository')我遇到的问题是在线上(在“LawFAQRepository”中)

entity.LawFAQLawCategories.Add(new LawFAQLawCategory(entity.Id, item));

I get an error:我得到一个错误:

System.NullReferenceException: Object reference not set to an instance of an object System.NullReferenceException:Object 引用未设置为 object 的实例

When I check the entity.Id it is 0. I know that the entity hasn't been saved in the database yet, and so it doesn't have the Id.当我检查entity.Id时,它是 0。我知道该实体还没有保存在数据库中,所以它没有 Id。 But as I searched, it has been written in link https://stackoverflow.com/questions/17523568/entity-framework-retrieve-id-before-savechanges-inside-a-transaction#:~:text=You%20can%20retreive%20an%20ID,it%20is%20added%20to%20dbcontext .但正如我搜索的那样,它已写在链接https://stackoverflow.com/questions/17523568/entity-framework-retrieve-id-before-savechanges-inside-a-transaction#:~:text=You%20can% 20retreive%20an%20ID,it%20is%20added%20to%20dbcontext

that before calling SaveChanges() method, we can retrieve the id (which is temporary and will be replaced later).在调用SaveChanges()方法之前,我们可以检索 id(这是临时的,稍后将被替换)。 I tested to see it by line我测试过按行查看

//PropertyEntry<LawFAQ, int> id = _context.Entry(entity).Property<int>("Id");

and I get a negative number as Id.我得到一个负数作为 Id。 But I don't know why I get an error if the entity.Id is 0 in line但是我不知道为什么如果entity.Id是 0 行我会报错

entity.LawFAQLawCategories.Add(new LawFAQLawCategory(entity.Id, item));

in LawFAQRepository .LawFAQRepository中。

And another point is that I can't make a new object of these entities from outside because of their protection level.另一点是,由于它们的保护级别,我无法从外部创建这些实体的新 object。 Even I tried to fill the 'LawFAQLawCategories' in LawFAQ entity itself but it has a same error.即使我试图在 LawFAQ 实体本身中填写“LawFAQLawCategories”,但它也有同样的错误。

Now my question is that how I can save data in LawFAQLawCategory table when I create a new LawFAQ object?现在我的问题是,当我创建一个新的LawFAQ object 时,如何将数据保存在LawFAQLawCategory表中?

Thank you in advance先感谢您

I solved the problem by changing the LawFAQRepository to我通过将 LawFAQRepository 更改为

using HW_R2.Application.Contracts.LawFAQ;
using HW_R2.Domain.LawFAQAgg;
using HW_R2.Domain.LawFAQLawCategoryAgg;
using Microsoft.EntityFrameworkCore;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;

namespace HW_R2.Infrastracture.EFCore.Repositories
{
    public class LawFAQRepository: ILawFAQRepository
    {
        private readonly HamedWebsire_Refac2Context _context;

        public LawFAQRepository(HamedWebsire_Refac2Context context)
        {
            _context = context;
        }

        public void Create(Create command)
        {

           
            var entity = _context.LawFAQs.Add(new LawFAQ(command.Question, command.Answer));

            var y = (int)entity.Property("Id").CurrentValue;
            var lawFAQLawCategory = new List<LawFAQLawCategory>();
            
            foreach (var item in command.LawCategoryIds)
            {
                lawFAQLawCategory.Add(new LawFAQLawCategory(y, item));  
            }
             entity.Navigation("LawFAQLawCategories").CurrentValue = lawFAQLawCategory;

            //PropertyEntry<LawFAQ, int> id = _context.Entry(entity).Property<int>("Id");
            Save();
        }
        public void Save()
        {
            _context.SaveChanges();
        }
    }
}

In Question, in 'Create(Create command)' method in 'LawFAQRepository',the entity in line在问题中,在'LawFAQRepository'中的'Create(Create command)'方法中,实体在行

var entity = new LawFAQ(command.Question, command.Answer);

hasn't been added to context(and in its next line it has been added to context), so it is obvious that its Id is 0.还没有被添加到上下文中(在它的下一行它已经被添加到上下文中),所以很明显它的 Id 是 0。

but in the Answer,the entity is但在答案中,实体是

var entity = _context.LawFAQs.Add(new LawFAQ(command.Question, command.Answer));

so its temporary Id has been produced and we don't get the error.所以它的临时 ID 已经生成,我们没有得到错误。

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

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