PostSharp.Samples.Xaml + EntityFramework

PostSharp.Samples.Xaml + EntityFramework

在将 PostSharp.Samples.Xaml 示例转换为使用 EntityFramework 时,我遇到 PostSharp inserting k__Backing Field into Entity Class, causing Database generation to fail 中提到的 "k__BackingField" 问题。你能告诉我如何使用建议的解决方案 "Use MulticastAttributeUsageAttribute.AttributeTargets to restrict it to properties." 而不会丢失 PostSharp 的 INotifyPropertyChanged 吗?我试图通过展示 EF 和 PS 来说服利益相关者。

这里是AddressModel.cs

的变化
using System;
using System.ComponentModel;
using System.Text;
using PostSharp.Patterns.Contracts;
using PostSharp.Patterns.Model;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;

namespace PostSharp.Samples.Xaml
{
    public class AddressModel : ModelBase
  {
    public int AddressId { get; set; }

    [DisplayName("Address Line 1")]
    [Patterns.Contracts.Required]
    public string Line1 { get; set; }

    [DisplayName("Address Line 2")]
    public string Line2 { get; set; }

    [Patterns.Contracts.Required]
    public string Town { get; set; }

    public string Country { get; set; }

    public DateTime Expiration { get; set; }

    [IgnoreAutoChangeNotification]
    public TimeSpan Lifetime => DateTime.Now - Expiration;

    [SafeForDependencyAnalysis]
    public string FullAddress
    {
        get
        {
            var stringBuilder = new StringBuilder();
            if (Line1 != null) stringBuilder.Append(Line1);
            if (Line2 != null)
            {
                if (stringBuilder.Length > 0) stringBuilder.Append("; ");
                stringBuilder.Append(Line2);
            }
            if (Town != null)
            {
                if (stringBuilder.Length > 0) stringBuilder.Append("; ");
                stringBuilder.Append(Town);
            }
            if (Country != null)
            {
                if (stringBuilder.Length > 0) stringBuilder.Append("; ");
                stringBuilder.Append(Country);
            }

            return stringBuilder.ToString();
        }
    }
        [ForeignKey("AddressId")]
        [Parent]
        public virtual CustomerModel Person { get; set; }
    }
}

app.config

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <configSections>
    <!-- For more information on Entity Framework configuration, visit http://go.microsoft.com/fwlink/?LinkID=237468 -->
    <section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
  </configSections>
  <runtime>
    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
      <dependentAssembly>
        <assemblyIdentity name="PostSharp" publicKeyToken="b13fd38b8f9c99d7" culture="neutral" />
        <bindingRedirect oldVersion="0.0.0.0-5.0.37.0" newVersion="5.0.37.0" />
      </dependentAssembly>
    </assemblyBinding>
  </runtime>
  <startup>
    <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.1" />
  </startup>
  <entityFramework>
    <defaultConnectionFactory type="System.Data.Entity.Infrastructure.LocalDbConnectionFactory, EntityFramework">
      <parameters>
        <parameter value="mssqllocaldb" />
      </parameters>
    </defaultConnectionFactory>
    <providers>
      <provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" />
    </providers>
  </entityFramework>
</configuration>

CustomerModel.cs

using System.IO;
using System.Threading;
using PostSharp.Patterns.Collections;
using PostSharp.Patterns.Contracts;
using PostSharp.Patterns.Model;
using PostSharp.Patterns.Threading;
using System;
using System.ComponentModel.DataAnnotations;
using PostSharp.Extensibility;

namespace PostSharp.Samples.Xaml
{
    public class CustomerModel : ModelBase
  {

    [Key]
    public int CustomerId { get; set; }

    public string FirstName { get; set; }

    [Patterns.Contracts.Required]
    public string LastName { get; set; }
    public string Phone { get; set; }
    public string Mobile { get; set; }
    public string Email { get; set; }

    [Child]
    public AdvisableCollection<AddressModel> Addresses { get; set; }

    [Reference]
    public AddressModel PrincipalAddress { get; set; }

    [Reader]
    public void Save(string path)
    {
      using (var stringWriter = new StreamWriter(path))
      {
        // We need to make sure the object graph is not being modified when we save,
        // and this is ensured by [ReaderWriterSynchronized] in ModelBase.

        stringWriter.WriteLine($"UserID: {CustomerId}");
        //Thread.Sleep(1000);

        stringWriter.WriteLine($"FirstName: {FirstName}");
        //Thread.Sleep(1000);

        stringWriter.WriteLine($"LastName: {LastName}");
        //Thread.Sleep(1000);

        stringWriter.WriteLine($"Phone: {Phone}");
        //Thread.Sleep(1000);

        stringWriter.WriteLine($"Mobile: {Mobile}");
        //Thread.Sleep(1000);

        stringWriter.WriteLine($"Email: {Email}");
        //Thread.Sleep(1000);

        foreach (var address in Addresses)
        {
          //Thread.Sleep(1000);

          if (address == PrincipalAddress)
            stringWriter.WriteLine($"Principal address: {address}");
          else
            stringWriter.WriteLine($"Secondary address: {address}");
        }

        try
        {
            using (var ctx = new EFContext())
            {
                ctx.Person.Add(this);
                ctx.SaveChanges();
            }

        }
        catch (Exception ex)
        {
            Console.WriteLine(ex.Message);

        }
      }
    }
  }
}

MainWindow.xaml

<Window x:Class="PostSharp.Samples.Xaml.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:xaml="clr-namespace:PostSharp.Samples.Xaml"
        xmlns:controls="clr-namespace:PostSharp.Patterns.Model.Controls;assembly=PostSharp.Patterns.Xaml"
        Title="Contact Form" Height="352.584" Width="352.753"
        x:Name="Window">
    <Window.DataContext>
        <xaml:CustomerViewModel />
    </Window.DataContext>
    <DockPanel>
        <ToolBarTray DockPanel.Dock="Top">
            <ToolBar>
                <Button Name="SaveButton" Command="{Binding ElementName=Window, Path=SaveCommand}">Save</Button>
                <controls:UndoButton />
                <controls:RedoButton />
            </ToolBar>
        </ToolBarTray>
        <Grid>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="29*" />
                <ColumnDefinition Width="316*" />
            </Grid.ColumnDefinitions>
            <Label Content="First Name:" HorizontalAlignment="Left" Margin="10,62,0,0" VerticalAlignment="Top"
                   Grid.ColumnSpan="2" />
            <TextBox HorizontalAlignment="Left" Height="23" Margin="97.846,62,0,0" TextWrapping="Wrap"
                     Text="{Binding Path=Customer.FirstName, ValidatesOnExceptions=True}" VerticalAlignment="Top"
                     Width="189" Grid.Column="1" />

            <Label Content="Last Name:" HorizontalAlignment="Left" Margin="10,88,0,0" VerticalAlignment="Top"
                   Grid.ColumnSpan="2" />
            <TextBox HorizontalAlignment="Left" Height="23" Margin="97.846,92,0,0" TextWrapping="Wrap"
                     Text="{Binding Path=Customer.LastName, ValidatesOnExceptions=True}" VerticalAlignment="Top"
                     Width="189" Grid.Column="1" />
            <Label Content="Principal Address:" HorizontalAlignment="Left" Margin="10,119,0,0" VerticalAlignment="Top"
                   RenderTransformOrigin="-0.105,-0.462" Grid.ColumnSpan="2" />
            <ComboBox HorizontalAlignment="Left" Margin="97.846,120,0,0" VerticalAlignment="Top" Width="189"
                      ItemsSource="{Binding Path=Customer.Addresses}"
                      SelectedValue="{Binding Path=Customer.PrincipalAddress}" DisplayMemberPath="FullAddress"
                      Grid.Column="1" />
            <xaml:FancyTextBlock HorizontalAlignment="Left" Margin="10,15,0,0" Text="{Binding Path=FullName}"
                                 VerticalAlignment="Top" Width="214" Grid.ColumnSpan="2" />
            <Label Content="Line1:" HorizontalAlignment="Left" Margin="11.846,150,0,0" VerticalAlignment="Top"
                   Grid.Column="1" />
            <TextBox HorizontalAlignment="Left" Height="23" Margin="97.846,154,0,0" TextWrapping="Wrap"
                     Text="{Binding Path=Customer.PrincipalAddress.Line1, ValidatesOnExceptions=True}"
                     VerticalAlignment="Top" Width="189" Grid.Column="1" />
            <Label Content="Town:" HorizontalAlignment="Left" Margin="12.846,176,0,0" VerticalAlignment="Top"
                   Grid.Column="1" />
            <TextBox HorizontalAlignment="Left" Height="23" Margin="97.846,182,0,0" TextWrapping="Wrap"
                     Text="{Binding Path=Customer.PrincipalAddress.Town, ValidatesOnExceptions=True}"
                     VerticalAlignment="Top" Width="189" Grid.Column="1" />
            <Label Content="User Id:" HorizontalAlignment="Left" Margin="11.846,210,0,0" VerticalAlignment="Top"
                   Grid.ColumnSpan="2" />
            <TextBox HorizontalAlignment="Left" Height="23" Margin="97.846,210,0,0" TextWrapping="Wrap"
                     Text="{Binding Path=Customer.UserID, ValidatesOnExceptions=True}" VerticalAlignment="Top"
                     Width="189" Grid.Column="1" />

        </Grid>
    </DockPanel>
</Window>

MainWindow.xaml.cs

using System.Windows;
using System.Windows.Input;
using Microsoft.Win32;
using PostSharp.Patterns.Collections;
using PostSharp.Patterns.Model;
using PostSharp.Patterns.Recording;
using PostSharp.Patterns.Threading;
using PostSharp.Patterns.Xaml;

namespace PostSharp.Samples.Xaml
{
    /// <summary>
    ///   Interaction logic for MainWindow.xaml
    /// </summary>
    [NotifyPropertyChanged]
    public partial class MainWindow : Window
    {
        /* private readonly */
        public readonly CustomerModel customer = new CustomerModel
        {
            Email = "2",
            Mobile = "3",
            Phone = "4",
            CustomerId = 1,
            FirstName = "Jan",
            LastName = "Novak",
            Addresses = new AdvisableCollection<AddressModel>
      {
        new AddressModel
        {
          Line1 = "Saldova 1G",
          Town = "Prague",
          Country = "USA"
        },
        new AddressModel
        {
          Line1 = "Tyrsova 25",
          Town = "Brno",
          Country = "USA"

        },
        new AddressModel
        {
          Line1 = "Pivorarka 154",
          Town = "Pilsen",
          Country = "USA"

        }
      }
        };

        private readonly Recorder recorder;

        public MainWindow()
        {
            // We need to have a local reference for [NotifyPropertyChanged] to work.
            recorder = RecordingServices.DefaultRecorder;


            InitializeComponent();

            // Register our custom operation formatter.
            RecordingServices.OperationFormatter = new MyOperationFormatter(RecordingServices.OperationFormatter);

      // Create initial data.
      var customerViewModel = new CustomerViewModel {Customer = customer};

      customerViewModel.Customer.PrincipalAddress = customerViewModel.Customer.Addresses[0];

            // Clear the initialization steps from the recorder.
            recorder.Clear();

      DataContext = customerViewModel;
    }

        [Command]
        public ICommand SaveCommand { get; private set; }

        public bool CanExecuteSave => recorder.UndoOperations.Count > 0;

        private void ExecuteSave()
        {
            var openFileDialog = new SaveFileDialog();

            if (openFileDialog.ShowDialog().GetValueOrDefault())
                Save(openFileDialog.FileName);
        }


        [Background]
        [DisableUI]
        private void Save(string path)
        {
            customer.Save(path);
        }
    }
}

packages.config

<?xml version="1.0" encoding="utf-8"?>
<packages>
  <package id="EntityFramework" version="6.2.0" targetFramework="net461" />
  <package id="PostSharp" version="5.0.40" targetFramework="net461" developmentDependency="true" />
  <package id="PostSharp.Patterns.Aggregation" version="5.0.40" targetFramework="net461" developmentDependency="true" />
  <package id="PostSharp.Patterns.Aggregation.Redist" version="5.0.40" targetFramework="net461" />
  <package id="PostSharp.Patterns.Common" version="5.0.40" targetFramework="net461" developmentDependency="true" />
  <package id="PostSharp.Patterns.Common.Redist" version="5.0.40" targetFramework="net461" />
  <package id="PostSharp.Patterns.Model" version="5.0.40" targetFramework="net461" developmentDependency="true" />
  <package id="PostSharp.Patterns.Model.Redist" version="5.0.40" targetFramework="net461" />
  <package id="PostSharp.Patterns.Threading" version="5.0.40" targetFramework="net461" developmentDependency="true" />
  <package id="PostSharp.Patterns.Threading.Redist" version="5.0.40" targetFramework="net461" />
  <package id="PostSharp.Patterns.Xaml" version="5.0.40" targetFramework="net461" developmentDependency="true" />
  <package id="PostSharp.Patterns.Xaml.Redist" version="5.0.40" targetFramework="net461" />
  <package id="PostSharp.Redist" version="5.0.40" targetFramework="net461" />
</packages>

PostSharp.Samples.Xaml.csproj

<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <Import Project="..\..\packages\PostSharp.5.0.40\build\PostSharp.props" Condition="Exists('..\..\packages\PostSharp.5.0.40\build\PostSharp.props')" />
  <Import Project="$(MSBuildExtensionsPath)$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)$(MSBuildToolsVersion)\Microsoft.Common.props')" />
  <PropertyGroup>
    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
    <ProjectGuid>{B10B8456-75F7-4D68-9775-CC87517B07B6}</ProjectGuid>
    <OutputType>WinExe</OutputType>
    <AppDesignerFolder>Properties</AppDesignerFolder>
    <RootNamespace>PostSharp.Samples.Xaml</RootNamespace>
    <AssemblyName>PostSharp.Samples.Xaml</AssemblyName>
    <TargetFrameworkVersion>v4.6.1</TargetFrameworkVersion>
    <FileAlignment>512</FileAlignment>
    <ProjectTypeGuids>{60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
    <WarningLevel>4</WarningLevel>
    <NuGetPackageImportStamp>
    </NuGetPackageImportStamp>
    <LangVersion>6</LangVersion>
    <TargetFrameworkProfile />
  </PropertyGroup>
  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
    <PlatformTarget>AnyCPU</PlatformTarget>
    <DebugSymbols>true</DebugSymbols>
    <DebugType>full</DebugType>
    <Optimize>false</Optimize>
    <OutputPath>bin\Debug\</OutputPath>
    <DefineConstants>DEBUG;TRACE</DefineConstants>
    <ErrorReport>prompt</ErrorReport>
    <WarningLevel>4</WarningLevel>
    <Prefer32Bit>false</Prefer32Bit>
  </PropertyGroup>
  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
    <PlatformTarget>AnyCPU</PlatformTarget>
    <DebugType>pdbonly</DebugType>
    <Optimize>true</Optimize>
    <OutputPath>bin\Release\</OutputPath>
    <DefineConstants>TRACE</DefineConstants>
    <ErrorReport>prompt</ErrorReport>
    <WarningLevel>4</WarningLevel>
    <Prefer32Bit>false</Prefer32Bit>
  </PropertyGroup>
  <ItemGroup>
    <Reference Include="EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089, processorArchitecture=MSIL">
      <HintPath>..\..\packages\EntityFramework.6.2.0\lib\net45\EntityFramework.dll</HintPath>
      <Private>True</Private>
    </Reference>
    <Reference Include="EntityFramework.SqlServer, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089, processorArchitecture=MSIL">
      <HintPath>..\..\packages\EntityFramework.6.2.0\lib\net45\EntityFramework.SqlServer.dll</HintPath>
      <Private>True</Private>
    </Reference>
    <Reference Include="PostSharp, Version=5.0.40.0, Culture=neutral, PublicKeyToken=b13fd38b8f9c99d7">
      <HintPath>..\..\packages\PostSharp.Redist.5.0.40\lib\net35-client\PostSharp.dll</HintPath>
      <Private>True</Private>
    </Reference>
    <Reference Include="PostSharp.Patterns.Aggregation">
      <HintPath>..\..\packages\PostSharp.Patterns.Aggregation.Redist.5.0.40\lib\net45\PostSharp.Patterns.Aggregation.dll</HintPath>
      <Private>True</Private>
    </Reference>
    <Reference Include="PostSharp.Patterns.Common">
      <HintPath>..\..\packages\PostSharp.Patterns.Common.Redist.5.0.40\lib\net46\PostSharp.Patterns.Common.dll</HintPath>
      <Private>True</Private>
    </Reference>
    <Reference Include="PostSharp.Patterns.Model">
      <HintPath>..\..\packages\PostSharp.Patterns.Model.Redist.5.0.40\lib\net40\PostSharp.Patterns.Model.dll</HintPath>
      <Private>True</Private>
    </Reference>
    <Reference Include="PostSharp.Patterns.Threading">
      <HintPath>..\..\packages\PostSharp.Patterns.Threading.Redist.5.0.40\lib\net45\PostSharp.Patterns.Threading.dll</HintPath>
      <Private>True</Private>
    </Reference>
    <Reference Include="PostSharp.Patterns.Xaml">
      <HintPath>..\..\packages\PostSharp.Patterns.Xaml.Redist.5.0.40\lib\net40\PostSharp.Patterns.Xaml.dll</HintPath>
      <Private>True</Private>
    </Reference>
    <Reference Include="System" />
    <Reference Include="System.ComponentModel.DataAnnotations" />
    <Reference Include="System.Data" />
    <Reference Include="System.Xml" />
    <Reference Include="Microsoft.CSharp" />
    <Reference Include="System.Core" />
    <Reference Include="System.Xml.Linq" />
    <Reference Include="System.Data.DataSetExtensions" />
    <Reference Include="System.Xaml">
      <RequiredTargetFramework>4.0</RequiredTargetFramework>
    </Reference>
    <Reference Include="WindowsBase" />
    <Reference Include="PresentationCore" />
    <Reference Include="PresentationFramework" />
  </ItemGroup>
  <ItemGroup>
    <ApplicationDefinition Include="App.xaml">
      <Generator>MSBuild:Compile</Generator>
      <SubType>Designer</SubType>
    </ApplicationDefinition>
    <Page Include="FancyTextBlock.xaml">
      <SubType>Designer</SubType>
      <Generator>MSBuild:Compile</Generator>
    </Page>
    <Page Include="MainWindow.xaml">
      <Generator>MSBuild:Compile</Generator>
      <SubType>Designer</SubType>
    </Page>
    <Compile Include="AddressModel.cs" />
    <Compile Include="App.xaml.cs">
      <DependentUpon>App.xaml</DependentUpon>
      <SubType>Code</SubType>
    </Compile>
    <Compile Include="CustomerModel.cs" />
    <Compile Include="CustomerViewModel.cs" />
    <Compile Include="DisableUIAttribute.cs" />
    <Compile Include="EFContext.cs" />
    <Compile Include="FancyTextBlock.xaml.cs">
      <DependentUpon>FancyTextBlock.xaml</DependentUpon>
    </Compile>
    <Compile Include="MainWindow.xaml.cs">
      <DependentUpon>MainWindow.xaml</DependentUpon>
      <SubType>Code</SubType>
    </Compile>
  </ItemGroup>
  <ItemGroup>
    <Compile Include="ModelBase.cs" />
    <Compile Include="MyOperationFormatter.cs" />
    <Compile Include="Properties\AssemblyInfo.cs">
      <SubType>Code</SubType>
    </Compile>
    <Compile Include="Properties\Resources.Designer.cs">
      <AutoGen>True</AutoGen>
      <DesignTime>True</DesignTime>
      <DependentUpon>Resources.resx</DependentUpon>
    </Compile>
    <Compile Include="Properties\Settings.Designer.cs">
      <AutoGen>True</AutoGen>
      <DependentUpon>Settings.settings</DependentUpon>
      <DesignTimeSharedInput>True</DesignTimeSharedInput>
    </Compile>
    <EmbeddedResource Include="Properties\Resources.resx">
      <Generator>ResXFileCodeGenerator</Generator>
      <LastGenOutput>Resources.Designer.cs</LastGenOutput>
    </EmbeddedResource>
    <None Include="app.config" />
    <None Include="packages.config" />
    <None Include="Properties\Settings.settings">
      <Generator>SettingsSingleFileGenerator</Generator>
      <LastGenOutput>Settings.Designer.cs</LastGenOutput>
    </None>
    <AppDesigner Include="Properties\" />
    <None Include="README.md" />
  </ItemGroup>
  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
  <Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
    <PropertyGroup>
      <ErrorText>This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them.  For more information, see http://go.microsoft.com/fwlink/?LinkID=322105.The missing file is {0}.</ErrorText>
    </PropertyGroup>
    <Error Condition="!Exists('..\..\packages\PostSharp.5.0.40\build\PostSharp.props')" Text="$([System.String]::Format('$(ErrorText)', '..\..\packages\PostSharp.5.0.40\build\PostSharp.props'))" />
    <Error Condition="!Exists('..\..\packages\PostSharp.5.0.40\build\PostSharp.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\packages\PostSharp.5.0.40\build\PostSharp.targets'))" />
  </Target>
  <Import Project="..\..\packages\PostSharp.5.0.40\build\PostSharp.targets" Condition="Exists('..\..\packages\PostSharp.5.0.40\build\PostSharp.targets')" />
  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
       Other similar extension points exist, see Microsoft.Common.targets.
  <Target Name="BeforeBuild">
  </Target>
  <Target Name="AfterBuild">
  </Target>
  -->

其他一切都保持不变,当您更改应用程序中的任何字段并尝试保存时,您应该能够构建它并在 CustomerModel.cs 行 #80 中看到异常。

您获得关注 ex.Message;

One or more validation errors were detected during model generation:

PostSharp.Samples.Xaml.AddressModel: : EntityType 'AddressModel' has no key defined. Define the key for this EntityType.
<Person>k__BackingField: Name: The specified name is not allowed: '<Person>k__BackingField'.
PostSharp.Samples.Xaml.AddressModel_<Person>k__BackingField: Name: The specified name is not allowed: 'AddressModel_<Person>k__BackingField'.
AddressModel_<Person>k__BackingField_Source: Name: The specified name is not allowed: 'AddressModel_<Person>k__BackingField_Source'.
AddressModel_<Person>k__BackingField_Target: Name: The specified name is not allowed: 'AddressModel_<Person>k__BackingField_Target'.
AddressModels: EntityType: EntitySet 'AddressModels' is based on type 'AddressModel' that has no keys defined.
AddressModel_<Person>k__BackingField: Name: The specified name is not allowed: 'AddressModel_<Person>k__BackingField'.

原始示例解决方案中没有的新文件,EFContext.cs:

using System.Data.Entity;

namespace PostSharp.Samples.Xaml
{
    public class EFContext :DbContext
    {
        public DbSet<CustomerModel> Person { get; set; }
    }
}

您可以在运行时使用 OnModelCreatingmodelBuilder.Entity<T>.Ignore(x => x.Property) 以编程方式忽略失败的 属性。下面演示了对 EFContext 的更改:

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
    IgnorePostSharpProperties<CustomerModel>(modelBuilder);
    IgnorePostSharpProperties<AddressModel>(modelBuilder);

    base.OnModelCreating(modelBuilder);

}

public void IgnorePostSharpProperties<T>(DbModelBuilder modelBuilder)
    where T : class
{
    foreach (PropertyInfo property in typeof(T).GetProperties(BindingFlags.NonPublic | BindingFlags.Instance))
    {
        // We don't want properties that are compiler-generated with a special PostSharp name.
        if (!property.IsDefined(typeof(CompilerGeneratedAttribute), false) || !property.Name.Contains("<"))
            continue;

        ParameterExpression paramExpression = Expression.Parameter(typeof(T));
        Expression expression = Expression.Lambda(
            Expression.Property(paramExpression, property.Name),
            paramExpression
            );

        EntityTypeConfiguration<T> entityTypeConfig = modelBuilder.Entity<T>();
        MethodInfo ignoreMethodDefinition = entityTypeConfig.GetType().GetMethod("Ignore", BindingFlags.Public | BindingFlags.Instance);
        MethodInfo ignoreMethodInstance = ignoreMethodDefinition.MakeGenericMethod(property.PropertyType);

        // Ignore the property.
        ignoreMethodInstance.Invoke(entityTypeConfig, new object[] {expression});
    }
}