Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/290.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
C# 实体框架更新查找表正在向另一个表添加项_C#_Entity Framework - Fatal编程技术网

C# 实体框架更新查找表正在向另一个表添加项

C# 实体框架更新查找表正在向另一个表添加项,c#,entity-framework,C#,Entity Framework,我对查找表有问题。 我有一个表格,允许我从一个团队的列表中选择颜色。 更新方法如下所示: [HttpPut] [Route("")] /// <summary> /// Update a team /// </summary> /// <param name="model">The team model</param> /// <returns>Nothing</returns> public async Task<I

我对查找表有问题。 我有一个表格,允许我从一个团队的列表中选择颜色。 更新方法如下所示:

[HttpPut]
[Route("")]
/// <summary>
/// Update a team
/// </summary>
/// <param name="model">The team model</param>
/// <returns>Nothing</returns>
public async Task<IHttpActionResult> Update(TeamBindingViewModel model)
{

    // If our model is invalid, return the errors
    if (!ModelState.IsValid)
        return BadRequest(ModelState);

    // Get our current team
    var team = await this.service.GetAsync(model.Id, "Colours");

    // Make changes to our team
    team.Name = model.Name;
    team.Sport = model.Sport;

    // Find out which colours need adding and removing
    var coloursToRemove = GetDifference(team.Colours, model.Colours);
    var coloursToAdd = GetDifference(model.Colours, team.Colours);

    // Loop through our colours to remove and remove them
    if (coloursToRemove.Count() > 0)
        foreach (var colour in coloursToRemove)
            team.Colours.Remove(colour);

    // Loop through the colours to add and add them
    if (coloursToAdd.Count() > 0)
        foreach (var colour in coloursToAdd)
            team.Colours.Add(colour);

    // Update the team
    this.service.Update(team);

    // Save the database changes
    await this.unitOfWork.SaveChangesAsync();

    // Return Ok
    return Ok(model);
}

private IList<Colour> GetDifference(IList<Colour> firstList, IList<Colour> secondList)
{

    // Create a new list
    var list = new List<Colour>();

    // Loop through the first list
    foreach (var first in firstList)
    {

        // Create a boolean and set to false
        var found = false;

        // Loop through the second list
        foreach (var second in secondList)
        {

            // If the first item id is the same as the second item id
            if (first.Id == second.Id)
            {

                // Mark it has being found
                found = true;
            }
        }

        // After we have looped through the second list, if we haven't found a match
        if (!found)
        {

            // Add the item to our list
            list.Add(first);
        }
    }

    // Return our differences
    return list;
}
因此,当执行saveChangesSync代码时,将生成以下SQL:

Started transaction at 13/04/2015 12:25:03 +01:00

UPDATE [dbo].[Teams]
SET [Name] = @0, [Sport] = @1
WHERE ([Id] = @2)

-- @0: 'Testing' (Type = String, Size = -1)

-- @1: 'ultimate-frisbee' (Type = String, Size = -1)

-- @2: '1' (Type = Int32)

-- Executing asynchronously at 13/04/2015 12:25:03 +01:00

-- Completed in 5 ms with result: 1



INSERT [dbo].[Colours]([Name], [Hex])
VALUES (@0, @1)
SELECT [Id]
FROM [dbo].[Colours]
WHERE @@ROWCOUNT > 0 AND [Id] = scope_identity()


-- @0: 'Red (Pms200)' (Type = String, Size = -1)

-- @1: 'ff0000' (Type = String, Size = -1)

-- Executing asynchronously at 13/04/2015 12:25:03 +01:00

-- Completed in 1 ms with result: SqlDataReader



INSERT [dbo].[TeamColours]([TeamId], [ColourId])
VALUES (@0, @1)

-- @0: '1' (Type = Int32)

-- @1: '43' (Type = Int32)

-- Executing asynchronously at 13/04/2015 12:25:03 +01:00

-- Completed in 1 ms with result: 1



Committed transaction at 13/04/2015 12:25:03 +01:00

Closed connection at 13/04/2015 12:25:03 +01:00
现在的问题是,它应该只在teamcolors表中插入一些内容,而不是colors表。 我不明白为什么

因为有人要看我的UnitOfWork课程,这里是:

public class UnitOfWork<TContext> : IUnitOfWork where TContext : DbContext, new()
{
    private readonly DbContext context;
    private Dictionary<Type, object> repositories;

    public DbContext Context { get { return this.context; } }

    public UnitOfWork()
    {
        this.context = new TContext();
        repositories = new Dictionary<Type, object>();
    }

    public IRepository<TEntity> GetRepository<TEntity>() where TEntity : class
    {
        if (repositories.Keys.Contains(typeof(TEntity)))
            return repositories[typeof(TEntity)] as IRepository<TEntity>;

        var repository = new Repository<TEntity>(context);

        repositories.Add(typeof(TEntity), repository);

        return repository;
    }

    public async Task SaveChangesAsync()
    {
        try
        {
            await this.context.SaveChangesAsync();
        }
        catch (DbUpdateConcurrencyException ex)
        {
            ex.Entries.First().Reload();
        }
    }

    public void Dispose()
    {
        this.context.Dispose();
    }
}
public类UnitOfWork:IUnitOfWork其中TContext:DbContext,new()
{
私有只读DbContext上下文;
私人词典库;
public DbContext Context{get{返回this.Context;}}
公共工作单元()
{
this.context=new TContext();
存储库=新字典();
}
public IRepository GetRepository(),其中tenty:class
{
if(repositories.Keys.Contains(typeof(tenty)))
将存储库[typeof(tenty)]返回为IRepository;
var repository=新存储库(上下文);
添加(typeof(tenty),repository);
返回存储库;
}
公共异步任务SaveChangesAsync()
{
尝试
{
等待这个.context.saveChangesSync();
}
捕获(DbUpdateConcurrencyException ex)
{
例如Entries.First().Reload();
}
}
公共空间处置()
{
this.context.Dispose();
}
}

尽管我确信这不会导致问题。

Model.Colors与上下文无关。因此,您的数据库上下文尝试添加新的数据库

1-从存储库获取颜色

var newColours = repository.ListColours(model.Colors.Select(m=>m.Id));  
2-为团队分配新颜色

team.Colours = newColours;

this.service.Update(team);

await this.unitOfWork.SaveChangesAsync();
EF将自动执行删除和添加操作

我还没有测试过这段代码。但我希望整个框架比我想的更聪明

试试这个

public async Task<IHttpActionResult> Update(TeamBindingViewModel model)
{
    // If our model is invalid, return the errors
    if (!ModelState.IsValid)
        return BadRequest(ModelState);

    // Get our current team
    var team = await this.service.GetAsync(model.Id, "Colours");

    // Make changes to our team
    team.Name = model.Name;
    team.Sport = model.Sport;

    //remove
    foreach (var colour in team.Colours.ToList())
    {
        if (!model.Colours.Any(c => c.Id == colour.Id))
            team.Colours.Remove(colour);
    }

    //add
    foreach (var colour in model.Colours)
    {
        if (!team.Colours.Any(c => c.Id == colour.Id))
            team.Colours.Add(colour);
    }

    // Update the team
    this.service.Update(team);

    // Save the database changes
    await this.unitOfWork.SaveChangesAsync();

    // Return Ok
    return Ok(model);
}
公共异步任务更新(TeamBindingViewModel模型)
{
//如果我们的模型无效,请返回错误
如果(!ModelState.IsValid)
返回请求(ModelState);
//让我们现在的团队
var team=wait this.service.GetAsync(model.Id,“colors”);
//改变我们的团队
team.Name=model.Name;
team.Sport=model.Sport;
//除去
foreach(team.colors.ToList()中的var color)
{
如果(!model.colors.Any(c=>c.Id==color.Id))
团队。颜色。移除(颜色);
}
//加
foreach(型号中的var颜色。颜色)
{
如果(!team.colors.Any(c=>c.Id==color.Id))
团队。颜色。添加(颜色);
}
//更新团队
本.服务.更新(团队);
//保存数据库更改
等待此消息。unitOfWork.SaveChangesSync();
//返回Ok
返回Ok(型号);
}

你在unitOfWork.saveChangesSync()中做什么,你能分享一下它的代码吗?编辑:我也是一个初学者,但我认为您使用的是不同的上下文,这不是更新现有行,而是添加新行,而且在我看来,上述方法中的代码也值得保留。这可能是使用存储库模式隐藏EF的一个缺点。。。您可能需要
附加
已传递
模型的部分颜色。除非它们被
DbContext
状态跟踪器跟踪,否则EF将假定它们是新的。另一种方法是从存储库中选择
color
的实例,并将其添加到
团队。colors
替代。您好,这导致了相同的问题。您的设计可能有一些问题,,,我认为它一定能工作。。。显示更多细节如果我在没有颜色的时候用它来添加颜色,效果很好。如果在有颜色的情况下尝试使用此选项,则在保存不公开其关系的外键属性的实体时,它无法说明发生了错误。EntityEntries属性将返回null,因为无法将单个实体标识为异常源。通过在实体类型中公开外键属性,可以更轻松地在保存时处理异常。查看InnerException了解详细信息。”,是的,看起来EF不够聪明,无法自动删除和添加记录。
public async Task<IHttpActionResult> Update(TeamBindingViewModel model)
{
    // If our model is invalid, return the errors
    if (!ModelState.IsValid)
        return BadRequest(ModelState);

    // Get our current team
    var team = await this.service.GetAsync(model.Id, "Colours");

    // Make changes to our team
    team.Name = model.Name;
    team.Sport = model.Sport;

    //remove
    foreach (var colour in team.Colours.ToList())
    {
        if (!model.Colours.Any(c => c.Id == colour.Id))
            team.Colours.Remove(colour);
    }

    //add
    foreach (var colour in model.Colours)
    {
        if (!team.Colours.Any(c => c.Id == colour.Id))
            team.Colours.Add(colour);
    }

    // Update the team
    this.service.Update(team);

    // Save the database changes
    await this.unitOfWork.SaveChangesAsync();

    // Return Ok
    return Ok(model);
}