如果我有一个LINQ to SQL表,其中有一个名为alias的字段。
然后有一个名为OnAliasChanging(字符串值)的方法存根;
我想要做的是获取值,检查数据库是否已存在该值,然后将值设置为已输入的值。
所以我可能会将我的别名从“griegs”更改为“slappy”,如果存在slappy,那么我想恢复已经存在的“griegs”值。
所以我有;
partial void OnaliasChanging(string value)
{
string prevValue = this.alias;
this.Changed = true;
}
当我检查prevValue的值时,它总是为空。
如何获取字段的当前值?
更新
如果我实现类似的东西;
partial void OnaliasChanging(string value)
{
if (this.alias != null)
this.alias = "TEST VALUE";
}
它会进入一个不健康的infinte循环。
如果我检查别名是否已经==“TEST VALUE”,则infinate循环仍然保留,因为该值始终是原始值。
有办法做到这一点吗?
答案 0 :(得分:1)
你发布的代码片段不适合任何合理的解释,为什么你最终会有无限循环。我认为this.alias
可能是一个属性,而不是字符大小写所暗示的字段,但需要看到更多。如果它是属性,那么在设置属性之前调用OnAliasChanging
方法;因此,尝试在同一方法中再次设置它将始终导致无限循环。通常,设计此方案的方法是在Cancel
OnXyzChanging
衍生产品中实施EventArgs
属性,或者将旧值保存在OnXyzChanging
方法中,然后执行检查如果您不能使用第一个(更好)选项,则在OnXyzChanged
方法中回滚/滚动。
从根本上说,你要做的事情一般不是很好的设计,而且违背了Linq to SQL的原则。 Linq to SQL实体应该是一个POCO,根本不了解兄弟实体或底层数据库。对每个属性更改执行重复检查不仅需要访问DataContext
或SqlConnection
,还会导致技术上称为副作用(打开新的数据库连接和/或默默地丢弃财产变更)。这种设计只是为了在路上发生神秘的撞车而尖叫。
事实上,您的特定场景是DataContext
类首先可扩展的主要原因之一。这种类型的操作属于那里。假设此处的实体名为User
,其中包含表Users
。
partial class MyDataContext
{
public bool ChangeAlias(Guid userID, string newAlias)
{
User userToChange = Users.FirstOrDefault(u => u.ID == userID);
if ((userToChange == null) || Users.Any(u => u.Alias == newAlias))
{
return false;
}
userToChange.Alias = newAlias;
// Optional - remove if consumer will make additional changes
SubmitChanges();
return true;
}
}
这封装了您要执行的操作,但不会阻止使用者直接更改Alias
属性。 如果你可以忍受这个,我会在那里停下来 - 你的数据库本身仍然应该有一个UNIQUE约束,所以这个方法可以简单地记录下来并用作安全尝试更改名称的方法,而不会在以后发生约束违规的风险(虽然总有某些风险 - 除非将所有内容放入事务或存储过程中,否则仍然可能存在竞争条件)。
如果您绝对必须限制对底层属性的访问,则执行此操作的一种方法是隐藏原始属性并创建只读包装器。在Linq设计器中,单击Alias
属性,然后在属性表上将访问更改为Internal
,将名称更改为{{ 1}}(但不要触及来源!)。最后,为实体创建一个部分类(我将在与AliasInternal
部分类相同的文件中执行此操作)并为该属性编写只读包装:
MyDataContext
您还必须将partial class User
{
public string Alias
{
get { return AliasInternal; }
}
}
方法中的Alias
引用更新为ChangeAlias
。
请注意,这可能会破坏尝试对新AliasInternal
包装器进行过滤/分组的查询(我相信Linq会抱怨它无法找到SQL映射)。该属性本身可以作为访问器使用,但如果您需要在Alias
上执行查找,那么您可能需要在Alias
中使用另一个GetUserByAlias
辅助方法,一个可以执行“真实的“查询MyDataContext
。
当你决定除了域逻辑之外你想要搞乱Linq的数据访问逻辑时,事情开始有点冒险,这就是为什么我在上面建议你只保留AliasInternal
属性并适当记录其用法。 Linq是围绕乐观并发而设计的;通常,当您需要在应用程序中强制执行UNIQUE约束时,请等待实际保存更改,然后在发生约束时处理约束违规。如果你想立即做到这一点,你的任务会变得更加困难,这就是这种冗长和普遍存在的原因。
再一次 - 我建议反对创建只读包装器的附加步骤;无论如何,我已经提出了一些代码,以防你的规范出于某种原因需要它。
答案 1 :(得分:0)
是否因为OnaliasChanging在初始化期间触发而挂起,因此您的支持字段(别名)永远不会被初始化,因此它始终为空?
没有更多的背景,这对我来说就是这样。