私はこの複雑な状況を持っています:主キーが「Id」と呼ばれる列のコード(nvarchar(3))と「祖先」のすべてのキー列(地域/州/都市)。
そのため、国テーブルには 1 つのキー列 (Id) しかありませんが、都市には 4 つのキー列 (Id、StateId、regionId、CountryId) があります。明らかにそれらはすべて関連しているため、各先祖列は関連テーブルへの外部キーです。
モデルには、この関係をマッピングするエンティティがあります。ただし、それらはすべて Entity<T> と呼ばれる 1 つの型から派生します。ここで、T は単純な型 (文字列など) または複雑な型 (キーを実装するコンポーネント) の場合があります。Entity<T> は、タイプ T の Id と呼ばれる単一のプロパティを実装します。
各 db テーブルに対して、comlex キーがある場合は、それを別のコンポーネントに実装します。このコンポーネントは、Equals および GetHashCode() メソッドもオーバーライドします (将来的には、これらをエンティティ基本クラスに実装します)。
したがって、2 つのプロパティ (Id と CountryId) を持つ RegionKey コンポーネントがあります。外部キーと主キーの命名とタイプには規則があり、それで問題ありません。また、複雑なエンティティごとに ovverride をマッピングしています。
簡単にするために、国と地域の表だけに注目してみましょう。どうぞ:
public class Country: Entity<string>
{
public virtual string Name { get; set; }
public virtual IList<Region> Regions { get; set; }
}
public class Region: Entity<RegionKey>
{
public virtual string Name { get; set; }
public virtual Country Country { get; set; }
}
および RegionKey コンポーネント:
namespace Hell.RealHellState.Api.Entities.Keys
{
[Serializable]
public class RegionKey
{
public virtual string Id { get; set; }
public virtual string CountryId { get; set; }
public override bool Equals(object obj)
{
if (obj == null)
return false;
var t = obj as RegionKey;
if (t == null)
return false;
return Id == t.Id && CountryId == t.CountryId;
}
public override int GetHashCode()
{
return (Id + "|" + CountryId).GetHashCode();
}
}
}
AutoPersistenceModel の構成は次のとおりです。
public ISessionFactory CreateSessionFactory()
{
return Fluently.Configure()
.Database(
MsSqlCeConfiguration.Standard
.ConnectionString(x=>x.Is(_connectionString))
)
.Mappings(m => m.AutoMappings.Add(AutoMappings))
.ExposeConfiguration(BuildSchema)
.BuildSessionFactory();
}
private AutoPersistenceModel AutoMappings()
{
return AutoMap.Assembly(typeof (Country).Assembly)
.IgnoreBase(typeof(Entity<>))
.Conventions.AddFromAssemblyOf<DataFacility>()
.UseOverridesFromAssembly(GetType().Assembly)
.Where(type => type.Namespace.EndsWith("Entities"));
}
private static void BuildSchema(Configuration config)
{
//Creates database structure
new SchemaExport(config).Create(false, true);
//new SchemaUpdate(config).Execute(false, true);
}
Regions エンティティのオーバーライドは次のとおりです。
public class RegionMappingOverride : IAutoMappingOverride<Region>
{
public void Override(AutoMapping<Region> mapping)
{
mapping.CompositeId(x=>x.Id)
.KeyProperty(x => x.Id, x=> x.ColumnName("Id").Length(3).Type(typeof(string)))
.KeyProperty(x => x.CountryId, x => x.ColumnName("CountryId").Length(3).Type(typeof(string)));
}
}
さて、このマッピングをテストすると、「リレーションシップの列のデータ型が一致しません」というエラーが表示されました。
私もこのオーバーライドを試しました:
public void Override(AutoMapping<Region> mapping)
{
mapping.CompositeId()
.ComponentCompositeIdentifier(x=>x.Id)
.KeyProperty(x => x.Id.Id, x=> x.ColumnName("Id").Length(3).Type(typeof(string)))
.KeyProperty(x => x.Id.CountryId, x => x.ColumnName("CountryId").Length(3).Type(typeof(string)));
}
そして、それはほとんど機能しますが、varbinary(8000) の単一の列キーを持つ Regions テーブルを作成しますが、これは私が望むものではありません:
CREATE TABLE [hell_Regions] (
[Id] varbinary(8000) NOT NULL
, [Name] nvarchar(50) NULL
, [CountryId] nvarchar(3) NULL
);
GO
ALTER TABLE [hell_Regions] ADD CONSTRAINT [PK__hell_Regions__0000000000000153] PRIMARY KEY ([Id]);
GO
ALTER TABLE [hell_Regions] ADD CONSTRAINT [FK_Regions_Country] FOREIGN KEY ([CountryId]) REFERENCES [hell_Countries]([Id]) ON DELETE NO ACTION ON UPDATE NO ACTION;
GO
私にはすべて問題ないように見えるので、対処方法の手がかりがありません。
回答ありがとうございます