如何修改手工编码的 MVC 模型中的 linqtosqlEntityRef 对象?
我正在尝试建立自己的 mvc 模型,而不是让环境通过图形设计器工具创建一个模型。我曾希望这将使模型空间的各个部分保持单独的存储库变得更容易,但到目前为止,它只给我带来了悲伤。
我遇到的第一个问题是,entityref 类必须通过视图中的选择列表控件进行更新。我设法通过向每个实体引用添加内部 ID 字段来实现这一点,就像 Designer.cs 所做的那样。然而,它使模型类变得更加复杂,如下面的代码所示。
不幸的是,当我想显式更新控制器中的某些实体时,我现在遇到了问题。如果我手动设置 ID 字段,更新就会被删除,如果我更改实体,我会在保存时遇到异常。
我的模型
[Table(Name = "dbo.Jobs")]
public class Job {
[Column(IsPrimaryKey = true, IsDbGenerated = true, AutoSync = AutoSync.OnInsert)]
public int JobID { get; set; }
internal string _CompanyID; // string for legacy reasons
[Column(Storage = "_CompanyID")]
public string CompanyID{
get { return _CompanyID}
set {
if ((_CompanyID != value)) {
if (_MittlerOrg.HasLoadedOrAssignedValue) {
throw new System.Data.Linq.ForeignKeyReferenceAlreadyHasValueException();
}
_CompanyID = value;
}
}
}
internal EntityRef<Company> _Company;
[Association(Storage = "_Company", ThisKey = "CompanyID", OtherKey = "CompanyID", IsForeignKey = true)]
public Company Company {
get { return _Company.Entity; }
set {
Organization previousValue = this._Company.Entity;
if ((previousValue != value) || (_Company.HasLoadedOrAssignedValue == false)) {
if ((previousValue != null)) {
_Company.Entity = null;
}
_Company.Entity = value;
if (value != null) {
_CompanyID = value.OrganizationID;
} else {
_CompanyID = default(string);
}
}
}
}
// The contact depends on the choice of company and should be set
// inside an action method once the company is determined.
internal string _ContactID;
[Column(Storage = "_ContactID")]
public string ContactID {
get { return _ContactID; }
set {
if ((_ContactID != value)) {
if (_Contact.HasLoadedOrAssignedValue) {
throw new System.Data.Linq.ForeignKeyReferenceAlreadyHasValueException();
}
_ContactID = value;
}
}
}
internal EntityRef<User> _Contact;
[Association(Storage = "_Contact", ThisKey = "ContactID", OtherKey = "UserID", IsForeignKey = true)]
public User Contact {
get { return _Contact.Entity; }
set {
User previousValue = this._Contact.Entity;
if ((previousValue != value) || (_Contact.HasLoadedOrAssignedValue == false)) {
if ((previousValue != null)) {
_Contact.Entity = null;
}
_Contact.Entity = value;
if (value != null) {
_ContactID = value.UserID;
} else {
_ContactID = default(string);
}
}
}
}
}
导致问题的编辑功能就在这里。如果我在调试器中单步执行它,我会看到 fi.ContactID 已更新但未提交到数据库。
[HttpPost]
public ActionResult Edit(int id, FormCollection collection) {
var user = userrep.FetchByLogin(User.Identity.Name);
var job = jobrep.FetchByID(id);
try {
var oldvalue = job.CompanyID;
UpdateModel(job, "job");
if (oldvalue != job.CompanyID) {
if (job.CompanyID != null) {
job.ContactID = orgrep.FetchByID(job.CompanyID).DefaultContactID;
} else {
job.ContactID = default(string);
}
}
firep.Save();
return RedirectToAction("Index");
} catch (Exception e) {
}
}
知道如何让那些讨厌的实体引用表现出来吗?我在互联网上搜索,但所有模型层示例似乎只涵盖最简单的关系。我是否应该完全放弃该模型,转而通过 id 字段手动管理我的引用。
干杯, 达菲
I am trying to set up my own mvc model rather than letting the environment create one via the graphic designer tool. I had hoped that this would make it easier to keep separate repositories for parts of the model space but so far it has caused me nothing but grief.
The first problem I ran into was that the entityref classes had to be updated via a selectlist control in the view. I managed to get that to work by adding an interal ID field to every entityref much like designer.cs would do. However, it has made the model class quite a bit more complex as the code below demonstrates.
Unfortunately, I now run into a problem when I want to explicitly update some of the entities in the controller. If I manually set the ID field, the update is just dropped, if I change the entity I get an exception while saving.
My model
[Table(Name = "dbo.Jobs")]
public class Job {
[Column(IsPrimaryKey = true, IsDbGenerated = true, AutoSync = AutoSync.OnInsert)]
public int JobID { get; set; }
internal string _CompanyID; // string for legacy reasons
[Column(Storage = "_CompanyID")]
public string CompanyID{
get { return _CompanyID}
set {
if ((_CompanyID != value)) {
if (_MittlerOrg.HasLoadedOrAssignedValue) {
throw new System.Data.Linq.ForeignKeyReferenceAlreadyHasValueException();
}
_CompanyID = value;
}
}
}
internal EntityRef<Company> _Company;
[Association(Storage = "_Company", ThisKey = "CompanyID", OtherKey = "CompanyID", IsForeignKey = true)]
public Company Company {
get { return _Company.Entity; }
set {
Organization previousValue = this._Company.Entity;
if ((previousValue != value) || (_Company.HasLoadedOrAssignedValue == false)) {
if ((previousValue != null)) {
_Company.Entity = null;
}
_Company.Entity = value;
if (value != null) {
_CompanyID = value.OrganizationID;
} else {
_CompanyID = default(string);
}
}
}
}
// The contact depends on the choice of company and should be set
// inside an action method once the company is determined.
internal string _ContactID;
[Column(Storage = "_ContactID")]
public string ContactID {
get { return _ContactID; }
set {
if ((_ContactID != value)) {
if (_Contact.HasLoadedOrAssignedValue) {
throw new System.Data.Linq.ForeignKeyReferenceAlreadyHasValueException();
}
_ContactID = value;
}
}
}
internal EntityRef<User> _Contact;
[Association(Storage = "_Contact", ThisKey = "ContactID", OtherKey = "UserID", IsForeignKey = true)]
public User Contact {
get { return _Contact.Entity; }
set {
User previousValue = this._Contact.Entity;
if ((previousValue != value) || (_Contact.HasLoadedOrAssignedValue == false)) {
if ((previousValue != null)) {
_Contact.Entity = null;
}
_Contact.Entity = value;
if (value != null) {
_ContactID = value.UserID;
} else {
_ContactID = default(string);
}
}
}
}
}
The edit function that causes problems is here. If I step though it in the debugger I see that fi.ContactID gets updated but not committed to the DB.
[HttpPost]
public ActionResult Edit(int id, FormCollection collection) {
var user = userrep.FetchByLogin(User.Identity.Name);
var job = jobrep.FetchByID(id);
try {
var oldvalue = job.CompanyID;
UpdateModel(job, "job");
if (oldvalue != job.CompanyID) {
if (job.CompanyID != null) {
job.ContactID = orgrep.FetchByID(job.CompanyID).DefaultContactID;
} else {
job.ContactID = default(string);
}
}
firep.Save();
return RedirectToAction("Index");
} catch (Exception e) {
}
}
Any idea how to get those pesky entityrefs to behave? I searched up and down the internet but all model layer examples seem to cover the simplest relationships only. Should I just chuck the model completely in favor of managing my references manually though id fields.
Cheers,
Duffy
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
更新:我从来没有让这段代码正常工作,所以我最终切换回让 Visual Studio 通过拖放图形设计器生成 DataContext。
在更新数据库模式后,我仍然在修复关系链接上的名称方面遇到了一些麻烦(我仔细命名了数据库中的所有关系,但设计器工具似乎忽略了这些名称),但自从我发现 db.designer.cs文件可以在 xml 编辑器中打开,而不是使用 GUI,工作变得容易多了。
Update: I never got this piece of code to work robustly so I ended up switching back to letting visual studio generate the DataContext via the drag and drop graphical designer.
I still struggle a bit with fixing the names on the relationship links after an update of the db schema (I carefully name all relationships in the db but the designer tool seems to ignore those names) but since I discovered that the db.designer.cs file can be opened in an xml editor rather than with the GUI, the job got a lot easier.