私は次のエンティティを持つコードファーストベースのコンテキストを持っています:
public class City : IEquatable<City>
{
public City()
{
Posts = new List<Post>();
}
public City(string cityName) : this()
{
Name = cityName;
}
public virtual ICollection<Post> Posts { get; private set; }
public int Id { get; set; }
public string Name { get; private set; }
protected string LoweredName
{
get { return Name.ToLower(CultureInfo.CurrentCulture); }
}
public override bool Equals(object obj)
{
bool equals = false;
var city = obj as City;
if (city != null)
equals = Equals(city);
return equals;
}
public override int GetHashCode()
{
int idHash = Id.GetHashCode();
int nameHash = LoweredName.GetHashCode();
var hashCode = idHash ^ nameHash;
return hashCode;
}
public bool Equals(City other)
{
return Id == other.Id && LoweredName == other.Name.ToLower(CultureInfo.CurrentCulture);
}
}
public class Post : IEquatable<Post>
{
public Post()
{
Addresses = new List<PostalAddress>();
}
public virtual ICollection<PostalAddress> Addresses { get; private set; }
public virtual City City { get; set; }
public int Id { get; set; }
public string ZipCode { get; set; }
protected string LoweredZipCode { get { return ZipCode.ToLower(CultureInfo.CurrentCulture); } }
public bool Equals(Post other)
{
return Id == other.Id && City.Equals(other.City) && LoweredZipCode == other.ZipCode.ToLower(CultureInfo.CurrentCulture);
}
}
DbContextは、メソッドOnModelCreatingでこれらのエンティティを定義しました。
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
modelBuilder.Configurations.Add(new CityMap());
modelBuilder.Configurations.Add(new PostMap());
}
public class CityMap : EntityTypeConfiguration<City>
{
public CityMap()
{
// Primary Key
HasKey(t => t.Id);
// Properties
// Table & Column Mappings
ToTable("City");
Property(t => t.Id).HasColumnName("Id");
Property(t => t.Name)
.HasColumnName("Name")
.HasMaxLength(450);
}
}
public class PostMap : EntityTypeConfiguration<Post>
{
public PostMap()
{
// Primary Key
HasKey(t => t.Id);
// Properties
// Table & Column Mappings
ToTable("Post");
Property(t => t.Id)
.HasColumnName("Id");
Property(t => t.ZipCode)
.HasColumnName("ZipCode")
.HasMaxLength(450);
// Relationships
HasRequired(t => t.City)
.WithMany(t => t.Posts)
.Map(map => map.MapKey("CityId"));
}
}
いくつかのデータをPOCOオブジェクトとして読み取り、リストコレクションに挿入しました
public class PostImportObject : IEquatable<PostImportObject>
{
private string _city;
private string _loweredCity;
public string City
{
get { return _city; }
set
{
_city = value.CapitalizeFirstLetter();
_loweredCity = value.ToLower(CultureInfo.CurrentCulture);
}
}
public string ZipCode
{
get { return _zipValue; }
set { _zipValue = value.ToLower(CultureInfo.CurrentCulture); }
}
protected string LoweredCity
{
get { return _loweredCity; }
}
public override bool Equals(object obj)
{
bool equals = false;
var postImport = obj as PostImportObject;
if (postImport != null)
{
equals = Equals(postImport);
}
return equals;
}
public override int GetHashCode()
{
int ziphash = ZipCode.GetHashCode();
int cityHash = LoweredCity.GetHashCode();
var hashCode = ziphash ^ cityHash;
return hashCode;
}
public bool Equals(PostImportObject other)
{
bool equals = _loweredCity == other.City.ToLower(CultureInfo.CurrentCulture) && ZipCode == other.ZipCode;
return equals;
}
}
インポートリストとデータベースのデータもクエリすると、次のクエリで同じ例外が返されます。
using(var db = new DbContext())
{
var query1 = from post2 in db.Posts.Include("City")
join mergedPost in mergedPosts on new PostImportObject() {City = post2.City.Name, ZipCode = post2.ZipCode} equals new PostImportObject() {City = mergedPost.City, ZipCode = mergedPost.ZipCode} into joinedPosts
from joinedPost in joinedPosts.DefaultIfEmpty()
where joinedPosts==null
select post2;
var query2= from city1 in db.Cities
join postImportObject in mergedPosts on city1.Name equals postImportObject.City
join post1 in db.Posts on city1 equals post1.City
select post1;
}
query1またはquery2のAny()メソッドをクエリすると、次の例外が発生します。 インデックス(ゼロベース)は、ゼロ以上で引数リストのサイズ未満である必要があります。
同じテーマで別のトピックを作成して申し訳ありませんが、他のトピックで問題の解決策が見つかりませんでした。