@H_403_1@我有两个班:
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
而已.您可以像这样同步您的数据库和用户数据.而且AutoMapper和ValueInjecter都是非常有用和强大的工具,我深深的推荐你来看看那些.我希望你喜欢,快乐的编码:)