实体框架:将多个表映射到一个实体-Insert问题

时间:2010-01-12 18:02:50

标签: entity-framework mapping crud

今天我有一个实体框架问题。我有两个表:Projects和Projects_Rights

alt text http://www.zaczek.net/EF-stackoverflow.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)&amp; CurrentAccessRights__Implementation __(=右)。这可以通过设置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

现在,我可以将此视图映射为实体框架中的“表格”。 [Identity]和[Rights]被映射为计算列。

另一个触发器现在负责填写正确的身份和权利。在这里,我有另一个问题。如果我在Projekte_Rights表EF中插入多于一行,声称实体返回了多行。但这是另一个故事,超出了这个问题的范围。

1 个答案:

答案 0 :(得分:3)

如果您想要更精细地控制插件和更新您需要使用StoredProcedures进行插入/更新/删除操作。

不幸的是,更新/插入/删除的范围是实体,您无法更精细地配置Sproc(针对一个表)和标准T-SQL(针对另一个表)。

这意味着如果您需要覆盖Projekt_Rights表的控件,您也必须为Projekt表执行此操作。

查看this sample了解更多信息。

注意:如果你需要为插入执行此操作,遗憾的是你必须进行更新和删除。

希望这有帮助

亚历