如何使用EF6更新多对多表格

艾伦2

我有两节课:

public partial class ObjectiveDetail {
    public ObjectiveDetail() {
        this.SubTopics = new List<SubTopic>();
    }
    public int ObjectiveDetailId { get; set; }
    public int Number { get; set; }
    public string Text { get; set; }
    public virtual ICollection<SubTopic> SubTopics { get; set; }
}
public partial class SubTopic {
    public int SubTopicId { get; set; }
    public string Name { get; set; }
}

我有一个来自用户的ObjectiveDetail对象:

var web = {
 "objectiveDetailId":1,
 "number":1,
 "text":"datafromweb",
 "subTopics":[
              {"subTopicId":1,
               "name":"one"
              },
              {"subTopicId":3,
               "name":"three",
              }
             ]
}

和来自数据库的ObjectiveDetail:

var db = {
 "objectiveDetailId":1,
 "number":1,
 "text":"datafromdb",
 "subTopics":[
              {"subTopicId":1,
               "name":"one"
              },
              {"subTopicId":2,
               "name":"two",
              }
             ]
}

使用Entity Framework 6,我知道可以使用以下命令更新ObjectiveDetail类中的文本:

_uow.ObjectiveDetails.Update(web));

但是,如何在连接这两个表的多对多表中更新对ObjectiveDetail和SubTopics的引用。例如,在这里我希望这样做,以便对于ObjectiveDetail 1,将许多更改为引用subTopicId 1和3,而不是值1和2。请注意,ObjectiveDetail和SubTopic存储在表中,并且它们之间还有另一个表。这是DDL:

CREATE TABLE [dbo].[ObjectiveDetail] (
    [ObjectiveDetailId] INT            IDENTITY (1, 1) NOT NULL,
    [Text]              NVARCHAR (MAX) NOT NULL,
    [ObjectiveTopicId]  INT            NULL,
    CONSTRAINT [PK_ObjectiveDetail] PRIMARY KEY CLUSTERED ([ObjectiveDetailId] ASC),
);

CREATE TABLE [dbo].[ObjectiveTopic] (
    [ObjectiveDetailId] INT NOT NULL,
    [SubTopicId]        INT NOT NULL,
    CONSTRAINT [FK_ObjectiveTopicObjectiveDetail] FOREIGN KEY ([ObjectiveDetailId]) REFERENCES [dbo].[ObjectiveDetail] ([ObjectiveDetailId]),
    CONSTRAINT [FK_ObjectiveTopicSubTopic] FOREIGN KEY ([SubTopicId]) REFERENCES [dbo].[SubTopic] ([SubTopicId])
);

CREATE TABLE [dbo].[SubTopic] (
    [SubTopicId] INT             IDENTITY (1, 1) NOT NULL,
    [Name]       NVARCHAR (150)  NOT NULL,
    CONSTRAINT [PK_SubTopic] PRIMARY KEY CLUSTERED ([SubTopicId] ASC),
);

这是我拥有的EF映射:

public class ObjectiveDetailMap : EntityTypeConfiguration<ObjectiveDetail>
{
    public ObjectiveDetailMap()
    {
        // Primary Key
        this.HasKey(t => t.ObjectiveDetailId);
        // Relationships
        this.HasMany(t => t.SubTopics)
           .WithMany(t => t.ObjectiveDetails)
           .Map(m =>
           {
               m.ToTable("ObjectiveTopic");
               m.MapLeftKey("ObjectiveDetailId");
               m.MapRightKey("SubTopicId");
           });

    }
}
乌苏夫(Yusuf Uzun)

我认为您正在尝试模拟供用户使用的脱机模式。因此,当您从用户那里得到一些东西时,您希望将数据库与用户数据同步。我举一个例子,将您的问题超越了一步:)我添加了一个子主题,该子主题需要在数据库中进行更新。好的,这是代码:

static void Main(string[] args)
{
    //the database
    var ObjectiveDetails = new List<ObjectiveDetail>()
    {
        new ObjectiveDetail()
        {
            ObjectiveDetailId = 1,
            Number = 1,
            Text = "datafromdb",
            SubTopics = new List<SubTopic>()
            {
                new SubTopic(){ SubTopicId = 1, Name="one"}, //no change
                new SubTopic(){ SubTopicId = 2, Name="two"}, //to be deleted
                new SubTopic(){ SubTopicId = 4, Name="four"} //to be updated
            }
        }
    };

    //the object comes as json and serialized to defined object.
    var web = new ObjectiveDetail()
    {
        ObjectiveDetailId = 1,
        Number = 1,
        Text = "datafromweb",
        SubTopics = new List<SubTopic>()
        {
            new SubTopic(){ SubTopicId = 1, Name="one"}, //no change
            new SubTopic(){ SubTopicId = 3, Name="three"}, //new row
            new SubTopic(){ SubTopicId = 4, Name="new four"} //must be updated
        }
    };

    var objDet = ObjectiveDetails.FirstOrDefault(x => x.ObjectiveDetailId == web.ObjectiveDetailId);
    if (objDet != null)
    {
        //you can use AutoMapper or ValueInjecter for mapping and binding same objects
        //but it is out of scope of this question
        //update ObjectDetail
        objDet.Number = web.Number;
        objDet.Text = web.Text;
        var subtops = objDet.SubTopics.ToList();

        //Delete removed parameters from database
        //Entity framework can handle it for you via change tracking
        //subtopicId = 2 has been deleted 
        subtops.RemoveAll(x => !web.SubTopics.Select(y => y.SubTopicId).Contains(x.SubTopicId));

        //adds new items which comes from web
        //adds subtopicId = 3 to the list
        var newItems = web.SubTopics.Where(x => !subtops.Select(y => y.SubTopicId).Contains(x.SubTopicId)).ToList();
        subtops.AddRange(newItems);

        //this items must be updated
        var updatedItems = web.SubTopics.Except(newItems).ToList();

        foreach (var item in updatedItems)
        {
            var dbItem = subtops.First(x => x.SubTopicId == item.SubTopicId);
            dbItem.Name = item.Name;
        }

        //let's see is it working
        Console.WriteLine("{0}:\t{1}\t{2}\n---------",objDet.ObjectiveDetailId, objDet.Number, objDet.Text);
        foreach (var item in subtops)
        {
            Console.WriteLine("{0}: {1}", item.SubTopicId, item.Name);
        }
    }
    else
    {
         //insert new ObjectiveDetail
    }

    //In real scenario after doing everything you need to call SaveChanges or it's equal in your Unit of Work.
}

结果:

1:      1       datafromweb
---------
1: one
4: new four
3: three

而已。您可以像这样同步数据库和用户数据。而且AutoMapperValueInjecter都是非常有用且功能强大的工具,我强烈建议您看一看。希望您喜欢,编码愉快:)

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

EF6 多对多关系,多表连接表

来自分类Dev

如何让Glimpse与EF6配合使用?

来自分类Dev

如何使用EF6在c#模型中创建多列“参考”索引(联接索引)

来自分类Dev

使用SQL更新多对多表

来自分类Dev

EF6多对多插入

来自分类Dev

EF6动态获取表格

来自分类Dev

EF6动态获取表格

来自分类Dev

如何在EF6中使用临时表

来自分类Dev

如何使用EF6删除1,000行?

来自分类Dev

如何通过EF6使用group by从表中查询?

来自分类Dev

如何使用EF6的分组依据从表中查询?

来自分类Dev

EF6子实体未在多对多关系中更新

来自分类Dev

使用Hibernate + MySQL保存或更新多对多表

来自分类Dev

更新EF6时需要属性

来自分类Dev

EF6 Code First多对多,无集合

来自分类Dev

如何使用带有动态接受好友按钮的ajax发布来更新更多表格?

来自分类Dev

EF6:如何避免循环引用?

来自分类Dev

使用EF6的异步查询结果

来自分类Dev

在 EF6 中使用数据注释

来自分类Dev

如何在EF6 Code First中更新虚拟属性?

来自分类Dev

如何在EF6 Code First中更新虚拟属性?

来自分类Dev

带有代码优先EF6的多租户

来自分类Dev

在EF6中添加多对多视图

来自分类Dev

删除与EF6有多对多关系的实体记录

来自分类Dev

EF6未在多对多上填充属性

来自分类Dev

带有代码优先EF6的多租户

来自分类Dev

删除与EF6有多对多关系的实体记录

来自分类Dev

如何使用EF6 Code First创建和使用视图?

来自分类Dev

如何使用EF6 Code First创建和使用视图?