实体框架:将多个表映射为一个实体 - 插入问题
今天我有一个实体框架问题。我有两个表:项目和Projects_Rights实体框架:将多个表映射为一个实体 - 插入问题
alt text http://www.zaczek.net/EF-*.jpg
- 项目包含了一些项目...
- Project_Rights包含对每个标识(=用户)对每个项目的访问权限。该表由触发器/函数计算。
这些映射表放入一个实体是没有挑战:
class Project
{
int ID;
double AufwandGes;
DateTime CreatedOn;
...
int CurrentIdentity__Implementation__;
int CurrentAccessRights__Implementation__;
}
<EntitySetMapping Name="Projekt">
<EntityTypeMapping TypeName="IsTypeOf(Model.Projekt)">
<MappingFragment StoreEntitySet="Projekt">
<ScalarProperty Name="ID" ColumnName="ID" />
<ScalarProperty Name="AufwandGes" ColumnName="AufwandGes" />
<ScalarProperty Name="ChangedOn" ColumnName="ChangedOn" />
<ScalarProperty Name="CreatedOn" ColumnName="CreatedOn" />
<ScalarProperty Name="Kundenname" ColumnName="Kundenname" />
<ScalarProperty Name="Name" ColumnName="Name" />
</MappingFragment>
<MappingFragment StoreEntitySet="Projekt_Rights">
<ScalarProperty Name="ID" ColumnName="ID" />
<ScalarProperty Name="CurrentIdentity__Implementation__" ColumnName="Identity" />
<ScalarProperty Name="CurrentAccessRights__Implementation__" ColumnName="Right" />
</MappingFragment>
</EntityTypeMapping>
</EntitySetMapping>
选择项目之一:
var prjList = ctx.GetQuery<Project>()
// This condition is added automatically by a custom Linq Provider
.Where(p => p.CurrentIdentity__Implementation__ == Thread.CurrentPrincipal.Identity.ID);
我从更新想出如何防止实体框架CurrentIdentity__Implementation __(= Identity)& CurrentAccessRights__Implementation __(= Right)。这是通过设置StoreGeneratedPattern =“Computed”在SSDL中完成的。
<EntityType Name="Projekte_Rights">
<Key>
<PropertyRef Name="ID" />
</Key>
<Property Name="ID" Type="int" Nullable="false" />
<Property Name="Identity" Type="int" Nullable="false" StoreGeneratedPattern="Computed" />
<Property Name="Right" Type="int" Nullable="false" StoreGeneratedPattern="Computed" />
</EntityType>
我已经声明级联在我的SQL Server和SSDL删除。很棒!
我的问题是:如何防止实体框架从插入记录到Project_Rights表中?添加记录是通过触发器/函数完成的。
感谢您指点我正确的方向!
编辑:
我找到了另一种方式。感谢Alex帮助我离开这条道路。
我创建了一个查看
create view Projekte_with_Rights as
select tbl.*, r.[Identity], r.[Right]
from Projekte tbl
inner join Projekte_Rights r on tbl.ID = r.id
这种观点是可更新的。为了能够删除行我实现了这个触发:
create trigger Projekte_with_Rights_DeleteTrigger
ON Projekte_with_Rights
INSTEAD OF DELETE AS
BEGIN
DELETE FROM Projekte WHERE ID in (SELECT ID FROM deleted)
END
现在我可以映射这个观点在实体框架“表”。 [身份]和[权利]被映射为计算列。
另一个触发器现在负责填写正确的身份和权利。在这里,我有另一个问题。如果我在Projekte_Rights表中插入多于一行的信息,EF声称一个实体返回多个行。但这是另一个故事,超出了这个问题的范围。
如果您想要更精细地控制插入&更新,您需要使用StoredProcedures进行插入/更新/删除操作。
不幸的是,更新/插入/删除的范围是实体,无法获得更精细的配置Sproc(对于一个表)和标准T-SQL(对于其他表)。
这意味着如果您需要重写Projekt_Rights表的控制权,您还必须为Projekt表执行该控制。
查看更多this sample。
注意:如果你需要这样做插入,不幸的是你必须做更新和删除。
希望这有助于
亚历
+1:我害怕听到这个消息。谢谢你帮助我离开这个方向。我将尝试使用可更新视图的解决方案。 – Arthur 2010-01-13 09:15:56