尝试将EF和Automapper与嵌套DTO一起使用时获取NotSupportedException

时间:2013-07-24 22:20:29

标签: c# .net entity-framework entity-framework-4.1 automapper

我正在使用Queryable Extensions的Automapper,但我的相关表格存在问题。

这是一个测试架构

CREATE TABLE [dbo].[AddressTable](
    [AddressId] [int] NOT NULL,
    [AddressLine1] [varchar](50) NOT NULL,
    [AddressLine2] [varchar](50) NOT NULL,
 CONSTRAINT [PK_AddressTable] PRIMARY KEY CLUSTERED ([AddressId] ASC)
)

CREATE TABLE [dbo].[FooTable](
    [FooId] [int] NOT NULL,
    [MailingAddressId] [int] NULL,
    [ShippingAddressId] [int] NULL,
 CONSTRAINT [PK_FooTable] PRIMARY KEY CLUSTERED  ([FooId] ASC)
)

ALTER TABLE [dbo].[FooTable] ADD  CONSTRAINT [FK_FooTable_AddressTable_Mailing] FOREIGN KEY([MailingAddressId])
    REFERENCES [dbo].[AddressTable] ([AddressId])
ALTER TABLE [dbo].[FooTable] ADD  CONSTRAINT [FK_FooTable_AddressTable_Shipping] FOREIGN KEY([ShippingAddressId]) 
    REFERENCES [dbo].[AddressTable] ([AddressId])

INSERT INTO [dbo].[AddressTable] VALUES (1,'123 Fake St','Apt 1')
INSERT INTO [dbo].[AddressTable] VALUES (2,'345 Real Ave','')
INSERT INTO [dbo].[FooTable] VALUES (1,1,2)

我使用数据库优先方法生成了EDMX文件,然后我重命名了FooTable中地址的两个关联属性,并删除了AddressTable方面的两个属性。这是它生成的EDMX

<?xml version="1.0" encoding="utf-8"?>
<edmx:Edmx Version="2.0" xmlns:edmx="http://schemas.microsoft.com/ado/2008/10/edmx">
  <!-- EF Runtime content -->
  <edmx:Runtime>
    <!-- SSDL content -->
    <edmx:StorageModels>
    <Schema Namespace="TestDbModel.Store" Alias="Self" Provider="System.Data.SqlClient" ProviderManifestToken="2005" xmlns:store="http://schemas.microsoft.com/ado/2007/12/edm/EntityStoreSchemaGenerator" xmlns="http://schemas.microsoft.com/ado/2009/02/edm/ssdl">
        <EntityContainer Name="TestDbModelStoreContainer">
          <EntitySet Name="AddressTable" EntityType="TestDbModel.Store.AddressTable" store:Type="Tables" Schema="dbo" />
          <EntitySet Name="FooTable" EntityType="TestDbModel.Store.FooTable" store:Type="Tables" Schema="dbo" />
          <AssociationSet Name="FK_FooTable_AddressTable_Mailing" Association="TestDbModel.Store.FK_FooTable_AddressTable_Mailing">
            <End Role="AddressTable" EntitySet="AddressTable" />
            <End Role="FooTable" EntitySet="FooTable" />
          </AssociationSet>
          <AssociationSet Name="FK_FooTable_AddressTable_Shipping" Association="TestDbModel.Store.FK_FooTable_AddressTable_Shipping">
            <End Role="AddressTable" EntitySet="AddressTable" />
            <End Role="FooTable" EntitySet="FooTable" />
          </AssociationSet>
        </EntityContainer>
        <EntityType Name="AddressTable">
          <Key>
            <PropertyRef Name="AddressId" />
          </Key>
          <Property Name="AddressId" Type="int" Nullable="false" />
          <Property Name="AddressLine1" Type="varchar" Nullable="false" MaxLength="50" />
          <Property Name="AddressLine2" Type="varchar" Nullable="false" MaxLength="50" />
        </EntityType>
        <EntityType Name="FooTable">
          <Key>
            <PropertyRef Name="FooId" />
          </Key>
          <Property Name="FooId" Type="int" Nullable="false" />
          <Property Name="MailingAddressId" Type="int" />
          <Property Name="ShippingAddressId" Type="int" />
        </EntityType>
        <Association Name="FK_FooTable_AddressTable_Mailing">
          <End Role="AddressTable" Type="TestDbModel.Store.AddressTable" Multiplicity="0..1" />
          <End Role="FooTable" Type="TestDbModel.Store.FooTable" Multiplicity="*" />
          <ReferentialConstraint>
            <Principal Role="AddressTable">
              <PropertyRef Name="AddressId" />
            </Principal>
            <Dependent Role="FooTable">
              <PropertyRef Name="MailingAddressId" />
            </Dependent>
          </ReferentialConstraint>
        </Association>
        <Association Name="FK_FooTable_AddressTable_Shipping">
          <End Role="AddressTable" Type="TestDbModel.Store.AddressTable" Multiplicity="0..1" />
          <End Role="FooTable" Type="TestDbModel.Store.FooTable" Multiplicity="*" />
          <ReferentialConstraint>
            <Principal Role="AddressTable">
              <PropertyRef Name="AddressId" />
            </Principal>
            <Dependent Role="FooTable">
              <PropertyRef Name="ShippingAddressId" />
            </Dependent>
          </ReferentialConstraint>
        </Association>
      </Schema></edmx:StorageModels>
    <!-- CSDL content -->
    <edmx:ConceptualModels>
      <Schema Namespace="TestDbModel" Alias="Self" xmlns:annotation="http://schemas.microsoft.com/ado/2009/02/edm/annotation" xmlns="http://schemas.microsoft.com/ado/2008/09/edm">
        <EntityContainer Name="TestDbEntities" annotation:LazyLoadingEnabled="true">
          <EntitySet Name="AddressTables" EntityType="TestDbModel.AddressTable" />
          <EntitySet Name="FooTables" EntityType="TestDbModel.FooTable" />
          <AssociationSet Name="FK_FooTable_AddressTable_Mailing" Association="TestDbModel.FK_FooTable_AddressTable_Mailing">
            <End Role="AddressTable" EntitySet="AddressTables" />
            <End Role="FooTable" EntitySet="FooTables" />
          </AssociationSet>
          <AssociationSet Name="FK_FooTable_AddressTable_Shipping" Association="TestDbModel.FK_FooTable_AddressTable_Shipping">
            <End Role="AddressTable" EntitySet="AddressTables" />
            <End Role="FooTable" EntitySet="FooTables" />
          </AssociationSet>
        </EntityContainer>
        <EntityType Name="AddressTable">
          <Key>
            <PropertyRef Name="AddressId" />
          </Key>
          <Property Type="Int32" Name="AddressId" Nullable="false" />
          <Property Type="String" Name="AddressLine1" Nullable="false" MaxLength="50" FixedLength="false" Unicode="false" />
          <Property Type="String" Name="AddressLine2" Nullable="false" MaxLength="50" FixedLength="false" Unicode="false" />
        </EntityType>
        <EntityType Name="FooTable">
          <Key>
            <PropertyRef Name="FooId" />
          </Key>
          <Property Type="Int32" Name="FooId" Nullable="false" />
          <Property Type="Int32" Name="MailingAddressId" />
          <Property Type="Int32" Name="ShippingAddressId" />
          <NavigationProperty Name="MailingAddress" Relationship="TestDbModel.FK_FooTable_AddressTable_Mailing" FromRole="FooTable" ToRole="AddressTable" />
          <NavigationProperty Name="ShippingAddress" Relationship="TestDbModel.FK_FooTable_AddressTable_Shipping" FromRole="FooTable" ToRole="AddressTable" />
          </EntityType>
        <Association Name="FK_FooTable_AddressTable_Mailing">
          <End Type="TestDbModel.AddressTable" Role="AddressTable" Multiplicity="0..1" />
          <End Type="TestDbModel.FooTable" Role="FooTable" Multiplicity="*" />
          <ReferentialConstraint>
            <Principal Role="AddressTable">
              <PropertyRef Name="AddressId" />
            </Principal>
            <Dependent Role="FooTable">
              <PropertyRef Name="MailingAddressId" />
            </Dependent>
          </ReferentialConstraint>
        </Association>
        <Association Name="FK_FooTable_AddressTable_Shipping">
          <End Type="TestDbModel.AddressTable" Role="AddressTable" Multiplicity="0..1" />
          <End Type="TestDbModel.FooTable" Role="FooTable" Multiplicity="*" />
          <ReferentialConstraint>
            <Principal Role="AddressTable">
              <PropertyRef Name="AddressId" />
            </Principal>
            <Dependent Role="FooTable">
              <PropertyRef Name="ShippingAddressId" />
            </Dependent>
          </ReferentialConstraint>
        </Association>
        </Schema>
    </edmx:ConceptualModels>
    <!-- C-S mapping content -->
    <edmx:Mappings>
      <Mapping Space="C-S" xmlns="http://schemas.microsoft.com/ado/2008/09/mapping/cs">
        <EntityContainerMapping StorageEntityContainer="TestDbModelStoreContainer" CdmEntityContainer="TestDbEntities">
          <EntitySetMapping Name="AddressTables">
            <EntityTypeMapping TypeName="TestDbModel.AddressTable">
              <MappingFragment StoreEntitySet="AddressTable">
                <ScalarProperty Name="AddressLine2" ColumnName="AddressLine2" />
                <ScalarProperty Name="AddressLine1" ColumnName="AddressLine1" />
                <ScalarProperty Name="AddressId" ColumnName="AddressId" />
              </MappingFragment>
            </EntityTypeMapping>
          </EntitySetMapping>
          <EntitySetMapping Name="FooTables">
            <EntityTypeMapping TypeName="TestDbModel.FooTable">
              <MappingFragment StoreEntitySet="FooTable">
                <ScalarProperty Name="ShippingAddressId" ColumnName="ShippingAddressId" />
                <ScalarProperty Name="MailingAddressId" ColumnName="MailingAddressId" />
                <ScalarProperty Name="FooId" ColumnName="FooId" />
              </MappingFragment>
            </EntityTypeMapping>
          </EntitySetMapping>
        </EntityContainerMapping>
      </Mapping>
    </edmx:Mappings>
  </edmx:Runtime>
  <!-- EF Designer content (DO NOT EDIT MANUALLY BELOW HERE) -->
  <Designer xmlns="http://schemas.microsoft.com/ado/2008/10/edmx">
    <Connection>
      <DesignerInfoPropertySet>
        <DesignerProperty Name="MetadataArtifactProcessing" Value="EmbedInOutputAssembly" />
      </DesignerInfoPropertySet>
    </Connection>
    <Options>
      <DesignerInfoPropertySet>
        <DesignerProperty Name="ValidateOnBuild" Value="true" />
        <DesignerProperty Name="EnablePluralization" Value="True" />
        <DesignerProperty Name="IncludeForeignKeysInModel" Value="True" />
        <DesignerProperty Name="CodeGenerationStrategy" Value="None" />
      </DesignerInfoPropertySet>
    </Options>
    <!-- Diagram content (shape and connector positions) -->
    <Diagrams></Diagrams>
  </Designer>
</edmx:Edmx>

enter image description here

这是我的测试程序来显示我的问题

using System.Linq;
using AutoMapper;
using AutoMapper.QueryableExtensions;


namespace Sandbox_Console
{
    class Program
    {
        class FooDTO
        {
            public int FooId { get; set; }
            public AddressDTO MailingAddress { get; set; }
            public AddressDTO ShippingAddress { get; set; }
        }

        class AddressDTO
        {
            public string AddressLine1 { get; set; }
            public string AddressLine2 { get; set; }
        }

        static void Main()
        {
            Mapper.CreateMap<FooTable, FooDTO>();
            Mapper.CreateMap<AddressTable, AddressDTO>();

            Mapper.AssertConfigurationIsValid();

            using (var ctx = new TestDbEntities())
            {
                var collection = ctx.FooTables.Where(a => a.FooId == 1).Project().To<FooDTO>();

                foreach (var fooDTO in collection)
                {
                    System.Diagnostics.Debugger.Break();
                }
                System.Diagnostics.Debugger.Break();

            }
        }
    }
}

当我运行我的代码时,我在foreach循环中评估NotSupportedException时得到collection。这是异常的完整堆栈跟踪。

System.NotSupportedException was unhandled
  HResult=-2146233067
  Message=The LINQ expression node type 'Invoke' is not supported in LINQ to Entities.
  Source=System.Data.Entity
  StackTrace:
       at System.Data.Objects.ELinq.ExpressionConverter.NotSupportedTranslator.Translate(ExpressionConverter parent, Expression linq)
       at System.Data.Objects.ELinq.ExpressionConverter.TranslateExpression(Expression linq)
       at System.Data.Objects.ELinq.ExpressionConverter.MemberInitTranslator.TypedTranslate(ExpressionConverter parent, MemberInitExpression linq)
       at System.Data.Objects.ELinq.ExpressionConverter.TranslateExpression(Expression linq)
       at System.Data.Objects.ELinq.ExpressionConverter.TranslateLambda(LambdaExpression lambda, DbExpression input)
       at System.Data.Objects.ELinq.ExpressionConverter.MethodCallTranslator.SelectTranslator.Translate(ExpressionConverter parent, MethodCallExpression call)
       at System.Data.Objects.ELinq.ExpressionConverter.MethodCallTranslator.TypedTranslate(ExpressionConverter parent, MethodCallExpression linq)
       at System.Data.Objects.ELinq.ExpressionConverter.Convert()
       at System.Data.Objects.ELinq.ELinqQueryState.GetExecutionPlan(Nullable`1 forMergeOption)
       at System.Data.Objects.ObjectQuery`1.GetResults(Nullable`1 forMergeOption)
       at System.Data.Objects.ObjectQuery`1.System.Collections.Generic.IEnumerable.GetEnumerator()
       at System.Data.Entity.Internal.Linq.InternalQuery`1.GetEnumerator()
       at System.Data.Entity.Infrastructure.DbQuery`1.System.Collections.Generic.IEnumerable.GetEnumerator()
       at Sandbox_Console.Program.Main() in e:\Code\Sandbox Console\Sandbox Console\Program.cs:line 34
  InnerException: 

我知道这是错误背后的AddressDTO类的映射。从FooDTO中评论它们会使错误消失。

导致这种情况发生的相关集合我做错了什么?

0 个答案:

没有答案