0

私は次のエンティティを持つコードファーストベースのコンテキストを持っています:

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()メソッドをクエリすると、次の例外が発生します。 インデックス(ゼロベース)は、ゼロ以上で引数リストのサイズ未満である必要があります。

同じテーマで別のトピックを作成して申し訳ありませんが、他のトピックで問題の解決策が見つかりませんでした。

4

1 に答える 1

1

ELinq_UnsupportedConstantスタック トレースを見ると、翻訳されたバージョンのリソースに問題があると推測されます。このエラー メッセージの英語版は次のとおりです:タイプ '{0}' の定数値を作成できません。このコンテキストでは、プリミティブ型 ('{1}') のみがサポートされています。

あなたには2つの問題があると思います:

  1. の場合join、複合キーは匿名型である必要があります。PostImportObjectyourを の結合キーとして使用することはできませんquery1

  2. データベース テーブルをローカル リストに結合することはできません。

.AsEnumerable()ローカルリストに参加する前に、リスト全体をメモリにプルするために使用する必要があると思います:

var query = from post in context.Posts.Include(p => p.City).AsEnumerable()
            join mergedPost in mergedPosts 
               on new { City = post.City.Name, post.ZipCode } 
               equals new { mergedPost.City, mergedPost.ZipCode } 
               into joinedPosts
           from joinedPost in joinedPosts.DefaultIfEmpty()
           where joinedPost == null
           select post;
于 2012-12-18T21:15:07.893 に答える