Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/asp.net/33.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Asp.net 为实体框架中的多对多关系添加标签_Asp.net_Entity Framework_Asp.net Core_Entity Framework Core - Fatal编程技术网

Asp.net 为实体框架中的多对多关系添加标签

Asp.net 为实体框架中的多对多关系添加标签,asp.net,entity-framework,asp.net-core,entity-framework-core,Asp.net,Entity Framework,Asp.net Core,Entity Framework Core,我正在创建一个API端点,该端点创建一个新的对话,其中包含应该与对话关联的标记。我在我的域中的标签和对话之间建立了多对多关系,请参见下面的关系 Tag.cs using System; using System.Collections.Generic; namespace Conferency.Domain { public class Tag : IAuditable { public int Id { get; set; } public s

我正在创建一个API端点,该端点创建一个新的对话,其中包含应该与对话关联的标记。我在我的域中的标签和对话之间建立了多对多关系,请参见下面的关系

Tag.cs

using System;
using System.Collections.Generic;

namespace Conferency.Domain
{
    public class Tag : IAuditable
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public List<TalkTag> TalkTags { get; set; }
        public DateTime ModifiedAt { get; set; }
        public DateTime CreatedAt { get; set; }
    }
}
ConferencyContext.cs(已删除不相关的代码)

使用Microsoft.EntityFrameworkCore;
使用Microsoft.EntityFrameworkCore.ChangeTracking;
使用制度;
使用授予域;
名称空间协商.Data
{
公共类ConferencyContext:DbContext
{
公共DbSet会话{get;set;}
公共DbSet标记{get;set;}
公共DbSet TagTalks{get;set;}
模型创建时受保护的覆盖无效(ModelBuilder ModelBuilder)
{
modelBuilder.Entity()
.HasKey(s=>new{s.TalkId,s.TagId});
modelBuilder.Entity()
.HasOne(pt=>pt.Talk)
.WithMany(p=>p.TalkTags)
.HasForeignKey(pt=>pt.TalkId);
modelBuilder.Entity()
.HasOne(pt=>pt.Tag)
.WithMany(t=>t.TalkTags)
.HasForeignKey(pt=>pt.TagId);
基于模型创建(modelBuilder);
}
}
}
TalkViewModel.cs

using System;
using System.Collections.Generic;

namespace Conferency.Application.Models
{
    public class TalkViewModel
    {
        public string Name { get; set; }
        public string Url { get; set; }
        public List<String> Tags { get; set; }
    }
}
使用系统;
使用System.Collections.Generic;
命名空间conference.Application.Models
{
公共类TalkViewModel
{
公共字符串名称{get;set;}
公共字符串Url{get;set;}
公共列表标记{get;set;}
}
}
问题是我不知道如何创建一个对话及其标签(如果它们存在,请附加,如果不存在,请创建)。我不确定要以什么样的方式来实现这一点。我是否必须查询每个标记以检查它们是否存在,或者是否有可以使用的findOrCreate方法?如果尚未创建对话,如何创建TalkTag记录?是否有一种优雅的方式来实现这一点,我不理解

TalkRepository.cs

using System.Collections.Generic;
using Conferency.Domain;
using Microsoft.EntityFrameworkCore;
using System;
using System.Linq;
using System.Threading.Tasks;

namespace Conferency.Data
{
    public class TalkRepository : ITalkRepository
    {
        private ConferencyContext _context;

        public TalkRepository(ConferencyContext context)
        {
            _context = context;
        }

        public void Add(Talk entity)
        {
            _context.Add(entity);
        }

        public void AddWithTags(Talk entity, List<String> tags)
        {
            // Create Talk
            // Query for each tag
            // Create if they don't exist
            // Attach to talk
            // ??
        }

        public IEnumerable<Talk> GetAllTalks()
        {
            return _context.Talks
                .Include(c => c.TalkTags)
                .OrderBy(c => c.Presented)
                .ToList();
        }

        public Talk GetTalk(int id)
        {
            return _context.Talks
                .Include(c => c.TalkTags)
                .Where(c => c.Id == id)
                .FirstOrDefault();
        }

        public async Task<bool> SaveAllAsync()
        {
            return (await _context.SaveChangesAsync()) > 0;
        }
    }
}
using System;
using System.Collections.Generic;
using Conferency.Domain;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore;
using System.Linq;

namespace Conferency.Data
{
    public class TagRepository: ITagRepository
    {
        private ConferencyContext _context;

        public TagRepository(ConferencyContext context)
        {
            _context = context;
        }

        public void Add(Tag entity)
        {
            _context.Add(entity);
        }

        public List<Tag> FindOrCreateTags(List<string> tags)
        {
            List<Tag> _tags = new List<Tag>();
            tags.ForEach(t =>
            {
                try
                {
                    var tag = _context.Tags
                       .Where(c => c.Name == t)
                       .FirstOrDefault();

                    if (tag != null)
                    {
                        _tags.Add(tag);
                    }
                    else
                    {
                        Tag created = new Tag { Name = t };
                        this.Add(created);
                        _tags.Add(created);
                    }
                }
                catch (Exception ex)
                {

                }

            });

            return _tags;
        }

        public async Task<bool> SaveAllAsync()
        {
            return (await _context.SaveChangesAsync()) > 0;
        }
    }
}
使用System.Collections.Generic;
使用授予域;
使用Microsoft.EntityFrameworkCore;
使用制度;
使用System.Linq;
使用System.Threading.Tasks;
名称空间协商.Data
{
公共类TalkRepository:ITalkRepository
{
私人会议背景(context);;
公共演讲库(ConferencyContext)
{
_上下文=上下文;
}
公共无效添加(对话实体)
{
_添加(实体);
}
公共void AddWithTags(对话实体、列表标记)
{
//创造对话
//查询每个标记
//如果它们不存在,就创建它们
//附和谈话
// ??
}
公共IEnumerable GetAllTalks()
{
返回上下文
.包括(c=>c.TalkTags)
.OrderBy(c=>c.Presented)
.ToList();
}
公共谈话GetTalk(int-id)
{
返回上下文
.包括(c=>c.TalkTags)
.其中(c=>c.Id==Id)
.FirstOrDefault();
}
公共异步任务SaveAllAsync()
{
返回(wait_context.saveChangesSync())>0;
}
}
}
我是c#新手,我正在努力学习最佳实践,熟悉EF和ASP.NET Core,希望有人能帮助我走上正确的道路。如果您想看一看,完整的解决方案就在这里

我试着自己解决它,但我得到了一个NullPointerException,下面是我尝试的解决方案:

TalksController.cs

  [HttpPost()]
        public async Task<IActionResult> Post([FromBody]TalkViewModel model)
        {
            try
            {
                _logger.LogInformation("Creating a new Talk");

                List<Tag> tags = _tagRepo.FindOrCreateTags(model.Tags);

                Talk talk = new Talk { Name = model.Name, Url = model.Url };

                List<TalkTag> talkTags = new List<TalkTag>();
                tags.ForEach(tag =>
                {
                    var talkTag = new TalkTag { TagId = tag.Id, Talk = talk };
                    talkTags.Add(talkTag);
                });

                talk.TalkTags.AddRange(talkTags); // Exception being thrown here
                _repo.Add(talk);

                if (await _repo.SaveAllAsync())
                {
                    string newUri = Url.Link("TalkGet", new { id = talk.Id });
                    return Created(newUri, talk);
                }
                else
                {
                    _logger.LogWarning("Could not save Talk");
                }
            }
            catch (Exception ex)
            {
                _logger.LogError($"Threw exception while saving Talk: {ex}");
            }

            return BadRequest();
        }
    }
[HttpPost()]
公共异步任务帖子([FromBody]TalkViewModel)
{
尝试
{
_logger.LogInformation(“创建新对话”);
列表标签=_tagRepo.FindOrCreateTags(model.tags);
Talk Talk=new Talk{Name=model.Name,Url=model.Url};
List talkTags=新列表();
tags.ForEach(tag=>
{
var-talkTag=new-talkTag{TagId=tag.Id,Talk=Talk};
talkTags.添加(talkTag);
});
talk.TalkTags.AddRange(TalkTags);//此处引发异常
_回购加(谈);
如果(等待_repo.SaveAllAsync())
{
字符串newUri=Url.Link(“TalkGet”,new{id=talk.id});
创建的返回(newUri、talk);
}
其他的
{
_logger.LogWarning(“无法保存对话”);
}
}
捕获(例外情况除外)
{
_logger.LogError($“保存对话时引发异常:{ex}”);
}
返回请求();
}
}
TagRepository.cs

using System.Collections.Generic;
using Conferency.Domain;
using Microsoft.EntityFrameworkCore;
using System;
using System.Linq;
using System.Threading.Tasks;

namespace Conferency.Data
{
    public class TalkRepository : ITalkRepository
    {
        private ConferencyContext _context;

        public TalkRepository(ConferencyContext context)
        {
            _context = context;
        }

        public void Add(Talk entity)
        {
            _context.Add(entity);
        }

        public void AddWithTags(Talk entity, List<String> tags)
        {
            // Create Talk
            // Query for each tag
            // Create if they don't exist
            // Attach to talk
            // ??
        }

        public IEnumerable<Talk> GetAllTalks()
        {
            return _context.Talks
                .Include(c => c.TalkTags)
                .OrderBy(c => c.Presented)
                .ToList();
        }

        public Talk GetTalk(int id)
        {
            return _context.Talks
                .Include(c => c.TalkTags)
                .Where(c => c.Id == id)
                .FirstOrDefault();
        }

        public async Task<bool> SaveAllAsync()
        {
            return (await _context.SaveChangesAsync()) > 0;
        }
    }
}
using System;
using System.Collections.Generic;
using Conferency.Domain;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore;
using System.Linq;

namespace Conferency.Data
{
    public class TagRepository: ITagRepository
    {
        private ConferencyContext _context;

        public TagRepository(ConferencyContext context)
        {
            _context = context;
        }

        public void Add(Tag entity)
        {
            _context.Add(entity);
        }

        public List<Tag> FindOrCreateTags(List<string> tags)
        {
            List<Tag> _tags = new List<Tag>();
            tags.ForEach(t =>
            {
                try
                {
                    var tag = _context.Tags
                       .Where(c => c.Name == t)
                       .FirstOrDefault();

                    if (tag != null)
                    {
                        _tags.Add(tag);
                    }
                    else
                    {
                        Tag created = new Tag { Name = t };
                        this.Add(created);
                        _tags.Add(created);
                    }
                }
                catch (Exception ex)
                {

                }

            });

            return _tags;
        }

        public async Task<bool> SaveAllAsync()
        {
            return (await _context.SaveChangesAsync()) > 0;
        }
    }
}
使用系统;
使用System.Collections.Generic;
使用授予域;
使用System.Threading.Tasks;
使用Microsoft.EntityFrameworkCore;
使用System.Linq;
名称空间协商.Data
{
公共类标记存储库:ITagRepository
{
私人会议背景(context);;
公共标记库(上下文上下文)
{
_上下文=上下文;
}
公共无效添加(标记实体)
{
_添加(实体);
}
公共列表FindOrCreateTags(列表标记)
{
列表_标记=新列表();
tags.ForEach(t=>
{
尝试
{
var tag=\u context.Tags
.Where(c=>c.Name==t)
.FirstOrDefault();
如果(标记!=null)
{
_标签。添加(标签);
}
其他的
{
创建的标记=新标记{Name=t};
添加(已创建);
_标签。添加(创建);
using System;
using System.Collections.Generic;
using Conferency.Domain;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore;
using System.Linq;

namespace Conferency.Data
{
    public class TagRepository: ITagRepository
    {
        private ConferencyContext _context;

        public TagRepository(ConferencyContext context)
        {
            _context = context;
        }

        public void Add(Tag entity)
        {
            _context.Add(entity);
        }

        public List<Tag> FindOrCreateTags(List<string> tags)
        {
            List<Tag> _tags = new List<Tag>();
            tags.ForEach(t =>
            {
                try
                {
                    var tag = _context.Tags
                       .Where(c => c.Name == t)
                       .FirstOrDefault();

                    if (tag != null)
                    {
                        _tags.Add(tag);
                    }
                    else
                    {
                        Tag created = new Tag { Name = t };
                        this.Add(created);
                        _tags.Add(created);
                    }
                }
                catch (Exception ex)
                {

                }

            });

            return _tags;
        }

        public async Task<bool> SaveAllAsync()
        {
            return (await _context.SaveChangesAsync()) > 0;
        }
    }
}
public int TagId { get; set; }
public string TagName { get; set; }
public bool Selected { get; set; }
Talk talk = new Talk { Name = model.Name, Url = model.Url, TalkTags = new List<TalkTag>() };