【发布时间】:2016-04-27 01:26:32
【问题描述】:
我有三张桌子。 Word -> WordForm -> SampleSentence。每个Word 有不同的WordForms 然后每个表单可以有一个或多个SampleSentence
CREATE TABLE [dbo].[Word] (
[WordId] VARCHAR (20) NOT NULL,
[CategoryId] INT DEFAULT ((1)) NOT NULL,
[GroupId] INT DEFAULT ((1)) NOT NULL,
PRIMARY KEY CLUSTERED ([WordId] ASC),
CONSTRAINT [FK_WordWordCategory] FOREIGN KEY ([CategoryId]) REFERENCES [dbo].[WordCategory] ([WordCategoryId]),
CONSTRAINT [FK_WordWordGroup] FOREIGN KEY ([GroupId]) REFERENCES [dbo].[WordGroup] ([WordGroupId])
);
CREATE TABLE [dbo].[WordForm] (
[WordFormId] VARCHAR (20) NOT NULL,
[WordId] VARCHAR (20) NOT NULL,
[Primary] BIT DEFAULT ((0)) NOT NULL,
[PosId] INT NOT NULL,
[Definition] VARCHAR (MAX) NULL,
PRIMARY KEY CLUSTERED ([WordFormId] ASC),
CONSTRAINT [FK_WordFormPos] FOREIGN KEY ([PosId]) REFERENCES [dbo].[Pos] ([PosId]),
CONSTRAINT [FK_WordFormWord] FOREIGN KEY ([WordId]) REFERENCES [dbo].[Word] ([WordId])
);
CREATE TABLE [dbo].[SampleSentence] (
[SampleSentenceId] INT IDENTITY (1, 1) NOT NULL,
[WordFormId] VARCHAR (20) NOT NULL,
[Text] VARCHAR (MAX) NOT NULL,
CONSTRAINT [PK_SampleSentence] PRIMARY KEY CLUSTERED ([SampleSentenceId] ASC),
CONSTRAINT [FK_SampleSentenceWordForm] FOREIGN KEY ([WordFormId]) REFERENCES [dbo].[WordForm] ([WordFormId])
);
我将这些表中的数据传送到前端客户端,然后它会修改数据并添加或删除 WordForms 和 SampleSentences。
然后我将数据带回服务器。
实体框架是否可以通过某种方式检查我带回服务器并对数据库进行更改的对象的更改,或者我是否必须进行某种形式的比较,以检查之前和之后Word、WordForm 和 Sample Sentence 对象?
这里是我正在使用的 C# 对象供参考:
public class Word
{
public string WordId { get; set; } // WordId (Primary key) (length: 20)
public int CategoryId { get; set; } // CategoryId
public int GroupId { get; set; } // GroupId
// Reverse navigation
public virtual System.Collections.Generic.ICollection<WordForm> WordForms { get; set; } // WordForm.FK_WordFormWord
// Foreign keys
public virtual WordCategory WordCategory { get; set; } // FK_WordWordCategory
public virtual WordGroup WordGroup { get; set; } // FK_WordWordGroup
public Word()
{
CategoryId = 1;
GroupId = 1;
WordForms = new System.Collections.Generic.List<WordForm>();
}
}
public class WordForm
{
public string WordFormId { get; set; } // WordFormId (Primary key) (length: 20)
public string WordId { get; set; } // WordId (length: 20)
public bool Primary { get; set; } // Primary
public int PosId { get; set; } // PosId
public string Definition { get; set; } // Definition
// Reverse navigation
public virtual System.Collections.Generic.ICollection<SampleSentence> SampleSentences { get; set; } // SampleSentence.FK_SampleSentenceWordForm
// Foreign keys
public virtual Pos Pos { get; set; } // FK_WordFormPos
public virtual Word Word { get; set; } // FK_WordFormWord
public WordForm()
{
Primary = false;
SampleSentences = new System.Collections.Generic.List<SampleSentence>();
}
}
public class SampleSentence : AuditableTable
{
public int SampleSentenceId { get; set; } // SampleSentenceId (Primary key)
public string WordFormId { get; set; } // WordFormId (length: 20)
public string Text { get; set; } // Text
// Foreign keys
public virtual WordForm WordForm { get; set; } // FK_SampleSentenceWordForm
}
这是我到目前为止所能想到的,但这不包括检查 SampleSentence,我不知道该怎么做:
public async Task<IHttpActionResult> Put([FromBody]Word word)
{
var oldObj = db.WordForms
.Where(w => w.WordId == word.WordId)
.AsNoTracking()
.ToList();
var newObj = word.WordForms.ToList();
var upd = newObj.Where(n => oldObj.Any(o =>
(o.WordFormId == n.WordFormId) && (o.PosId != n.PosId || !o.Definition.Equals(n.Definition) )))
.ToList();
var add = newObj.Where(n => oldObj.All(o => o.WordFormId != n.WordFormId))
.ToList();
var del = oldObj.Where(o => newObj.All(n => n.WordFormId != o.WordFormId))
.ToList();
foreach (var wordForm in upd)
{
db.WordForms.Attach(wordForm);
db.Entry(wordForm).State = EntityState.Modified;
}
foreach (var wordForm in add)
{
db.WordForms.Add(wordForm);
}
foreach (var wordForm in del)
{
db.WordForms.Attach(wordForm);
db.WordForms.Remove(wordForm);
}
db.Words.Attach(word);
db.Entry(word).State = EntityState.Modified;
await db.SaveChangesAsync(User, DateTime.UtcNow);
return Ok(word);
}
【问题讨论】:
-
相关:stackoverflow.com/questions/9503286/…。无论如何,保持现有记录很重要吗?否则,您可以删除
Word并简单地重新插入已发布的Word。 -
艾伦,如果您可以使用 Jquery 检测更改并维护一个标志,您可以稍后将其发送到服务器端,然后决定是否要更新表,那么您可以减轻负担
-
自我跟踪实体怎么样?是的,不再推荐它们,但这并不意味着它们不能解决您的问题。
-
@CodeCaster - 我会考虑你的建议。这听起来像一个好主意。虽然在服务器端,我认为我需要有一种方法来识别所有新的 WordForm 和 SampleSentence,以便 EF 知道添加这些。
-
@Alan 您能解决您的问题吗?您是如何解决的?
标签: c# asp.net entity-framework