简体   繁体   English

无法使用Entity Framework Core 2.0更新或创建数据

[英]Can't update nor create data using Entity Framework Core 2.0

Edit: Got past the issue in the PUT (was a null value going into a non-null field), but still having issues with the POST 编辑:在PUT中解决了问题(将null值输入到非null字段中),但POST仍然存在问题

I'm trying to setup a simple generic repository in my project using EF Core 2. The Gets and the Updates work fine but I'm having issues with the Create. 我正在尝试使用EF Core 2在我的项目中设置一个简单的通用存储库。“获取”和“更新”工作正常,但是“创建”存在问题。 Specifically, the value received at HttpPost in the controller is null. 具体来说,在控制器的HttpPost处接收到的值为null。 What is weird is that the HttpPut works fine in the controller and the Company is received with all its data. 奇怪的是HttpPut在控制器中工作正常,并且公司收到了所有数据。

Here is my generic repo class: 这是我的通用仓库类:

public class GenericRepository<TEntity> : IGenericRepository<TEntity>
    where TEntity : class, IEntity
{
    protected DriverDbContext _dbContext;
    protected DbSet<TEntity> _dbSet;

    public GenericRepository(DriverDbContext dbContext)
    {
        _dbContext = dbContext;
        _dbSet = dbContext.Set<TEntity>();
    }

    public async Task<IEnumerable<TEntity>> GetAll()
    {
        return await _dbSet.AsNoTracking().ToListAsync();
    }

    public async Task<TEntity> GetById(long id)
    {
        return await _dbSet
            .AsNoTracking()
            .FirstOrDefaultAsync(e => e.Id == id);
    }

    public async Task Create(TEntity entity)
    {
        _dbSet.Add(entity);
        await _dbContext.SaveChangesAsync();
    }

    public async Task Update(TEntity entity)
    {
        // entity has good data but SavaChangesAsync does nothing
        _dbSet.Update(entity);
        await _dbContext.SaveChangesAsync();
    }

    public async Task Delete(long id)
    {
        var entity = await _dbSet.FindAsync(id);
        _dbSet.Remove(entity);
        await _dbContext.SaveChangesAsync();
    }

}

Here is my controller: 这是我的控制器:

[Produces("application/json")]
[Route("api/Company")]
public class CompanyController : Controller
{

    private ICompanyRepository _repository;

    public CompanyController(ICompanyRepository repository)
    {
        _repository = repository;
    }

    [HttpGet]
    public async Task<IActionResult> GetCompanies()
    {
        return Json(await _repository.GetAll());
    }

    [HttpGet("{id}")]
    public async Task<IActionResult> GetCompany(int id)
    {
        var company = await _repository.GetById(id);

        if (company == null)
        {
            return NotFound();
        }
        return Json(company);
    }

    [HttpPost()]
    public async Task<IActionResult> CreateCompany([FromBody]CompanyViewModel company)
    {
        if (company == null)
        {
            return BadRequest();
        }

        var newCompany = Mapper.Map<Company>(company);

        await _repository.Create(newCompany);

        return Created($"/api/company/{company.Name}", Mapper.Map<CompanyViewModel>(newCompany));

    }

    [HttpPut()]
    public async Task<IActionResult> UpdateCompany([FromBody]CompanyViewModel company)
    {
        if (company==null)
        {
            return BadRequest();
        }

        if (_repository.GetById(company.Id) == null)
        {
            return NotFound();
        }

        var updatedCompany = Mapper.Map<Company>(company);
        await _repository.Update(updatedCompany);
        return new NoContentResult();
    }
}

Here is the company entity: 这是公司实体:

public class Company : IEntity
{
    public long Id { get; set; }
    public string Name { get; set; }
    public string Address { get; set; }
    public string City { get; set; }
    public string State { get; set; }
    public string ZipCode { get; set; }
    public string Phone { get; set; }
    public string Email { get; set; }
    public string Comments { get; set; }
    public string Type { get; set; }
    public bool Blacklisted { get; set; }
    public string BlacklistedComments { get; set; }
    public string BrokerAgreementStatus { get; set; }
    public float CompanyInvoiceDiscount { get; set; }
    public float PassThroughFee { get; set; }
    public int StandardHoursBilled { get; set; }
    public float StandardGM { get; set; }
    public float StandardMarkupFromBase { get; set; }
    public float StandardMarkupFromLoaded { get; set; }
    public float StandardEquipmentCost { get; set; }
    public long LastEditByUserID { get; set; }
    public DateTime? LastEditDate { get; set; }
}

Here is the company view model: 这是公司视图模型:

public class CompanyViewModel
{
    public long Id { get; set; }
    public string Name { get; set; }
    public string Address { get; set; }
    public string City { get; set; }
    public string State { get; set; }
    public string ZipCode { get; set; }
    public string Phone { get; set; }
    public string Email { get; set; }
    public string Comments { get; set; }
    public string Type { get; set; }
    public bool Blacklisted { get; set; }
    public string BlacklistedComments { get; set; }
    public string BrokerAgreementStatus { get; set; }
    public float CompanyInvoiceDiscount { get; set; }
    public float PassThroughFee { get; set; }
    public int StandardHoursBilled { get; set; }
    public float StandardGM { get; set; }
    public float StandardMarkupFromBase { get; set; }
    public float StandardMarkupFromLoaded { get; set; }
    public float StandardEquipmentCost { get; set; }
    public long LastEditByUserId { get; set; }
    public DateTime LastEditDate { get; set; }
}

Here is my angular company service: 这是我的有角公司服务:

import { Injectable } from '@angular/core';
import { HttpClient, HttpHeaders } from '@angular/common/http';

import { Observable } from 'rxjs/Rx';
import { of } from 'rxjs/observable/of';
import { catchError, map, tap } from 'rxjs/operators';

import { Company } from './company';
import { MessageService } from '../message/message.service';

const httpOptions = {
    headers: new HttpHeaders({ 'Content-Type': 'application/json' })
};

@Injectable()
export class CompanyService {

    private baseUrl = 'api/company';

    constructor(
        private http: HttpClient,
        private messageService: MessageService) {
    }

    private log(message: string) {
        this.messageService.add('CompanyService: ' + message);
    }

    getCompanies(): Observable<Company[]> {
        return this.http.get<Company[]>(this.baseUrl)
            .pipe(
                tap(companies => this.log(`fetched companies`)),
                catchError(this.handleError('getCompanies', []))
                );
    }

    //Handle Http operation that failed.
    //Let the app continue.
    //@param operation - name of the operation that failed
    //@param result - optional value to return as the observable result

    getCompany(id: number): Observable<Company> {
        if (id === 0) {
            return Observable.of(this.initializeCompany());
        }
        return this.http.get<Company>(`${this.baseUrl}/${id}`).pipe(
            tap(_ => this.log(`fetched Company id=${id}`)),
            catchError(this.handleError<Company>(`getCompany id=${id}`))
        );
        }

    initializeCompany(): Company {
        return {
            id: 0,
            name: null,
            address: null,
            city: null,
            state: null,
        };
    }

    saveCompany(company: Company): Observable<Company> {
        if (company.id === null) {
            return this.addCompany(company);
        }
        return this.updateCompany(company);
    }

    updateCompany(company: Company): Observable<Company> {
        return this.http.put<Company>(this.baseUrl, company, httpOptions).pipe(
            tap((company: Company) => this.log(`updated company id=${company.id}`)),
            catchError(this.handleError<any>('updateCompany'))
        );
    }

    addCompany(company: Company): Observable<Company> {
        return this.http.post<Company>(this.baseUrl, company, httpOptions).pipe(
            tap((company: Company) => this.log(`added company id=${company.id}`)),
            catchError(this.handleError<any>('addCompany'))
        );
    }

    private handleError<T>(operation = 'operation', result?: T) {
        return (error: any): Observable<T> => {

            // TODO: send the error to remote logging infrastructure
            console.error(error); // log to console instead

            // TODO: better job of transforming error for user consumption
            //this.log(`${operation} failed: ${error.message}`);

            // Let the app keep running by returning an empty result.
            return of(result as T);
        };
    }


}

Here is the startup.cs 这是startup.cs

public class Startup
{

    private IConfiguration _config;

    public Startup(IConfiguration config)
    {
        _config = config;
    }

    // This method gets called by the runtime. Use this method to add services to the container.
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddDbContext<DriverDbContext>(options => options.UseSqlServer(_config.GetConnectionString("DriverDBConnection")));

        services.AddMvc();

        services.AddScoped<ICompanyRepository, CompanyRespository>();


    } 

    // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
    public void Configure(IApplicationBuilder app, IHostingEnvironment env)
    {
        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
            app.UseWebpackDevMiddleware(new WebpackDevMiddlewareOptions
            {
                HotModuleReplacement = true
            });
        }
        else
        {
            app.UseExceptionHandler("/Home/Error");
        }

        app.UseStaticFiles();

        Mapper.Initialize(config =>
        {
            config.CreateMap<CompanyViewModel, Company>().ReverseMap();
        });

        app.UseMvc(routes =>
        {
            routes.MapRoute(
                name: "default",
                template: "{controller=Home}/{action=Index}/{id?}");

            routes.MapSpaFallbackRoute(
                name: "spa-fallback",
                defaults: new { controller = "Home", action = "Index" });
        });
    }
}

The CompanyRespository is an empty child class of the GenericRepository CompanyRespository是GenericRepository的空子类

Here is the request payload to the Post: 这是到Post的请求有效负载:

{"id":null,
"name":"Some Company",
"address":null,
"city":null,
"state":"",
"zipcode":null,
"phone":null,
"email":null,
"comments":null,
"type":null,
"blacklisted":false,
"blacklistedComments":null,
"brokerAgreementStatus":"N/A",
"companyInvoiceDiscount":0,
"passThroughFee":0,
"standardHoursBilled":0,
"standardGM":0,
"standardMarkupFromBase":0,
"standardMarkupFromLoaded":0,
"standardEquipmentCost":0,
"lastEditByUserID":0,
"lastEditDate":"2018-01-10T23:03:05.303Z"}

Here is the Request Header 这是请求标题

Accept:application/json, text/plain, */*
Accept-Encoding:gzip, deflate, br
Accept-Language:en-US,en;q=0.9
Connection:keep-alive
Content-Length:447
Content-Type:application/json
Host:localhost:56241
Origin:http://localhost:56241
Referer:http://localhost:56241/companies/0/edit
User-Agent:Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36
public async Task Create(TEntity entity)
{
    _dbSet.Add(entity);
    await _dbContext.SaveChangesAsync();
}

public async Task Update(TEntity entity)
{
    // entity has good data but SavaChangesAsync does nothing
    _dbSet.Update(entity);
    _dbContext.Entry(entity).State = EntityState.Modified;
    await _dbContext.SaveChangesAsync();
}

public async Task Delete(long id)
{
    var entity = await _dbSet.FindAsync(id);
    if (_dbContext.Entry(entity).State = EntityState.Detached)
        _dbSet.Attach(entity);
    _dbSet.Remove(entity);
    await _dbContext.SaveChangesAsync();
}

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

相关问题 无法使用 Entity Framework Core 更新数据库 - Can't Update database with Entity Framework Core 如何使用Entity Framework Core 2.0为X实体创建链接的X实体 - How do I create linked X entities for a X entity using Entity Framework Core 2.0 Entity Framework Core 2.0迁移使用种子数据引发错误更新数据库 - Entity Framework Core 2.0 migrations update database with seed data throwing error Entity Framework Core 2.0 Add-Migration 不创建任何迁移文件 - Entity Framework Core 2.0 Add-Migration doesn't create any migration files 使用实体框架无法获取数据 - can't get data using entity framework 使用 .net core Entity Framework 从 JSON 创建嵌套数据 - Create nested data from JSON using .net core Entity Framework 无法在 Entity Framework Core 6 上插入具有导航属性的数据 - Can't insert data with navigation properties on Entity Framework Core 6 使用Dynamic Linq Core和Entity Framework 2.0创建包含列表的对象 - Create object containing a list using Dynamic Linq Core with Entity Framework 2.0 无法将 Entity Framework Core 迁移添加到 .NET 标准 2.0 项目 - Can't add Entity Framework Core migrations to .NET Standard 2.0 project 如何在Entity Framework Core 2.0上使用lambda语法在LINQ中实现LEFT OUTER JOIN? - How can I implement a LEFT OUTER JOIN in LINQ using lambda syntax on Entity Framework Core 2.0?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM