c# – 如何使用EF6更新多个表

前端之家收集整理的这篇文章主要介绍了c# – 如何使用EF6更新多个表前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我有两个班:
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,"text":"datafromdb",{"subTopicId":2,"name":"two",}
             ]
}

使用实体框架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,[Name]       NVARCHAR (150)  NOT NULL,CONSTRAINT [PK_SubTopic] PRIMARY KEY CLUSTERED ([SubTopicId] ASC),);

这是我有的EF Mapping:

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");
           });

    }
}

解决方法

我想您正在尝试模拟为您的用户工作的离线模式.所以当你从用户那里得到某些东西时,你想同步数据库用户数据.我举一个例子,把你的问题从一步超越:)我添加了一个需要在数据库中更新的Subtopic.好的,这里是代码
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,Text = "datafromweb",SubTopics = new List<SubTopic>()
        {
            new SubTopic(){ SubTopicId = 1,//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都是非常有用和强大的工具,我深深的推荐你来看看那些.我希望你喜欢,快乐的编码:)

猜你在找的C#相关文章