在实体框架中添加实体插入空记录

时间:2012-10-25 01:55:02

标签: asp.net-mvc entity-framework

我正在尝试在EF中插入一个新实体:

public class Ad
{
    // Primary properties
    public int Kms { get; set; }

    // Navigation properties
    public virtual Model Model { get; set; }
}

我从View中收到这样的模型(示例值):

kms = 222 Model.Id = 3

然后当我执行实体框架的Add和SaveChanges时,我在模型表中插入了一个NULL记录(生成了一个新ID),并在广告表中添加了一个带有新插入的模型ID的记录。

为什么会这样?

服务层:

    public void CreateAd(CreateAdDto adDto)
    {
        var adDomain = Mapper.Map<CreateAdDto, Ad>(adDto);

        _adRepository.Add(adDomain);
        _adRepository.Save();
    }

存储库:

    public void Add(T entity)
    {
        _dbSet.Add(entity);
    }

   public void Save()
    {
        try
        {
            _dataContext.SaveChanges();
        }
        catch (DbEntityValidationException e)
        {
            var s = e.EntityValidationErrors.ToList();
            throw;
        }
    }

视图模型:

public class CreateAdViewModel
{
    // Primary properties
    public string Version { get; set; }
    public int Kms { get; set; }
    public int Year { get; set; }
    public decimal Price { get; set; }

    public int Make_Id { get; set; }
    public int Model_Id { get; set; }

    // Navigation properties
    public IEnumerable<SelectListItem> MakeList { get; set; }
    public IEnumerable<SelectListItem> ModelList { get; set; }
}

DTO:

public class CreateAdDto
{
    // Primary properties
    public int Kms { get; set; }
    public int Model_Id { get; set; }
}

映射:

        Mapper.CreateMap<CreateAdDto, Ad>().ForMember(dest => dest.Model, opt => opt.MapFrom(src => new Model { Id = src.Model_Id }));

2 个答案:

答案 0 :(得分:1)

如果您只是在Add实例上调用Ad方法,则所有相关实体都将被视为新实体。因此,您可以先附加Model实例,然后添加Ad

context.Models.Attach(ad.Model);
context.Ads.Add(ad);
context.SaveChanges();

答案 1 :(得分:1)

基于@Eranga的解决方案答案(谢谢男人!)

希望这可以帮助别人,因为它可以帮助我感谢@Eranga。

正在发生的事情是,在从DTO到DOMAIN的映射中,Model实体正在从一个Model_Id到视图中的Dropdownlist到实体模型(正如您在问题中的映射行中所看到的那样)。

然后,当它通过Entity Framework添加到数据库时,EF不知道Ad Domain Entity中是否存在Model导航属性。

所以我必须创建解决此问题的方法是在我的存储库中添加一个新方法来处理将模型实体附加到广告实体上下文的可能性:

public void Attach(T entity)
{
    _dbSet.Attach(entity);
}

并在广告服务创建方法中添加附件:

    private readonly IRepository<Ad> _adRepository;
    private readonly IRepository<Search> _searchRepository;
    private readonly IRepository<Model> _modelRepository;


    public AdService(IRepository<Ad> adRepository, IRepository<Search> searchRepository, IRepository<Model> modelRepository)
    {
        _adRepository = adRepository;
        _searchRepository = searchRepository;
        _modelRepository = modelRepository;
    }

    public void CreateAd(CreateAdDto adDto)
    {
        var adDomain = Mapper.Map<CreateAdDto, Ad>(adDto);

        _modelRepository.Attach(adDomain.Model);

        _adRepository.Add(adDomain);
        _adRepository.Save();
    }

现在,当adDomain对象通过_adRepository.Add到达EF时,它已经知道导航属性Model的存在,并且可以添加新的adDomain ojbect。

之前,它发生的是,当adDomain对象到达EF时,EF不知道模型存在,因此它创建了一个空记录。

希望这有助于其他任何人。

问候。