1

きれいなモデル クラス ライブラリを作成するために、EF5 Code First を使用しています。EntityTypeConfiguration を使用すると、さまざまなプロパティが、SQL Server 2005 サーバー インスタンスでホストされる 2 つのビューの列にマップされます。

注意: テーブル列の名前付けに問題があることは承知していますが、これは既存のデータベースであるため、これに対処する必要があります。私を許してください。

配管を行った後、クライアント アカウントを照会できます...

var context = new Data.EntityContext();
public IQueryable<ClientAccount> GetClients(List<string> usernameOrEmail)
{
    return context.ClientAccount.Where(p => usernameOrEmail.Contains(p.UserName) || usernameOrEmail.Contains(p.Email)).Include("Company").AsQueryable();
}

...会社の詳細を含む、一致するクライアントが返されます。

ただし、会社のみのリストを取得しようとすると、結果に重複が多数含まれます。

var companies = data.Companies.Where(c => c.IsActive).OrderBy(c => c.Name);

SQL Server Profiler を使用して、私には不明な理由で、クライアントの userId も含めるために、エンジンが LEFT OUTER JOIN を考え出すことがわかりました。

SELECT 
    [Extent1].[Id] AS [Id], 
    [Extent1].[Company] AS [Company], 
    [Extent1].[Address] AS [Address], 
    [Extent1].[AddressSuffix] AS [AddressSuffix], 
    [Extent1].[Zip] AS [Zip], 
    [Extent1].[City] AS [City], 
    [Extent1].[State] AS [State], 
    [Extent1].[CountryName] AS [CountryName], 
    [Extent1].[Telephone] AS [Telephone], 
    [Extent1].[Fax] AS [Fax], 
    [Extent1].[Url] AS [Url], 
    [Extent1].[Latitude] AS [Latitude], 
    [Extent1].[Longitude] AS [Longitude], 
    [Extent1].[isPublic] AS [isPublic], 
    [Extent1].[active] AS [active], 
    [Extent1].[parent] AS [parent], 
    [Extent2].[userId] AS [userId]
FROM  [dbo].[VIEW_CompaniesCountryContinent] AS [Extent1]
    LEFT OUTER JOIN [dbo].[PassportAccounts] AS [Extent2] ON ([Extent2].[companyId] IS NOT NULL) AND ([Extent1].[Id] = [Extent2].[companyId])
WHERE 1 = [Extent1].[active]

Company モデルからクライアントへのリンクがないため、その理由がわかりません。VIEW には user テーブルは含まれず、companys テーブルのみを対象としています。

私が何かを見逃していることは明らかです。あなたが私を軌道に乗せてくれることを願っています。以下に、モデル、コンテキスト、およびエンティティ タイプの構成に関する詳細を示します。ありがとう!

コード情報:

モデルはかなり単純です...

public class ClientAccount : IUserAccount
{
    public ClientAccount() { }

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

    [DisplayName("User Name")]
    public string UserName { get; set; }

    [DisplayName("First Name")]
    public string FirstName { get; set; }

    [DisplayName("Last Name")]
    public string LastName { get; set; }

    [DisplayName("Job Title")]
    public string JobTitle { get; set; }

    [DisplayName("Company")]
    public virtual Company Company { get; set; }

    [DisplayName("Direct Phone")]
    public string PhoneDirect { get; set; }

    [DisplayName("Mobile phone")]
    public string PhoneMobile { get; set; }

    [DisplayName("Registration Date")]
    public DateTime DateRegistered { get; set; }

    [DisplayName("Last Login")]
    public DateTime LastLogin { get; set; }

    [EmailAddress]
    [DisplayName("Email")]
    public string Email { get;set; }

    public bool IsApproved { get; set; }
    public bool IsActive { get; set; }
    public bool IsLockedOut { get { return !IsActive; } }
    public bool IsOnline
    {
        get { return (LastLogin.AddMinutes(10) > DateTime.Now); }
    }

    public DateTime LastActivityAt  {   get; set; }
}

public class Company
{
    [Key]
    public int ID { get; set; }

    public string Name { get; set; }

    public string Address { get; set; }
    public string Address2 { get; set; }

    public string Zip { get; set; }
    public string City { get; set; }
    public string State { get; set; }

    public string Country { get; set; }

    public string Telephone { get; set; }
    public string Fax { get; set; }
    public string Url { get; set; }

    public string TimeZone { get; set; }
    public Coordinate Coordinate { get; set; }

    public bool IsPublic { get; set; }
    public bool IsActive { get; set; }

    public int ParentCompanyId { get; set; }

}

public class Coordinate
{       
    public decimal? Latitude { get; set; }
    public decimal? Longitude { get; set; }
}

これまでのところ、特別なことは何もありません(そうですか?)。DbContext : _

public class EntityContext : DbContext
{

    public EntityContext() : base("Name=EntityContext")
    {
        Database.SetInitializer<EntityContext>(null);
    }

    public EntityContext(string connectionString)
        : base(connectionString)
    {
        Database.SetInitializer<EntityContext>(null);
    }

    public DbSet<ClientAccount> ClientAccount { get; set; }
    public DbSet<Company> Companies { get; set; }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Configurations.Add(new CompanyConfiguration());
        modelBuilder.Configurations.Add(new ClientAccountConfiguration());

        base.OnModelCreating(modelBuilder);
    }
}

そしてEntityTypeConfigurations ...

public class ClientAccountConfiguration : EntityTypeConfiguration<ClientAccount>
{
    public ClientAccountConfiguration()
        : base()
    {
        HasKey(p => p.ClientId);

        ToTable("ClientAccounts"); // VIEW ClientAccounts

        Property(p => p.ClientId)
            .HasColumnName("userId")
            .HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity)
            .IsRequired();

        Property(p => p.Email)
            .HasColumnName("userEmail")
            .IsRequired();

        Property(p => p.UserName)
            .HasColumnName("userLogin")
            .IsRequired();

        Property(p => p.FirstName).HasColumnName("userFirstName");
        Property(p => p.LastName).HasColumnName("userLastName");
        Property(p => p.PhoneDirect).HasColumnName("userPhoneDirect");
        Property(p => p.PhoneMobile).HasColumnName("userPhoneMobile");

        Property(p => p.JobTitle)
            .HasColumnName("userPosition");

        HasOptional(p => p.Company)
            .WithOptionalDependent()
            .Map(p => p.MapKey("companyId"));

        Property(p => p.IsApproved).HasColumnName("Employed");
        Property(p => p.IsActive).HasColumnName("active");
        Property(p => p.LastActivityAt).HasColumnName("updated");
        Property(p => p.LastLogin).HasColumnName("LastLogin").IsOptional();
        Property(p => p.DateRegistered).HasColumnName("created");

    }
}

public class CompanyConfiguration : EntityTypeConfiguration<Company>
{
    public CompanyConfiguration()
    {
        this.HasKey(c => c.ID);


        this.ToTable("VIEW_CompaniesCountryContinent");
        this.Property(c => c.ID)
            .HasColumnName("Id")
            .HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);

        this.Property(c => c.Name)
            .HasColumnName("Company")
            .IsRequired();

        this.Property(c => c.Address).HasColumnName("Address");
        this.Property(c => c.Address2).HasColumnName("AddressSuffix");
        this.Property(c => c.Country).HasColumnName("CountryName");
        this.Property(c => c.City).HasColumnName("City");

        this.Property(c => c.Zip).HasColumnName("Zip");
        this.Property(c => c.State).HasColumnName("State");

        this.Property(c => c.Coordinate.Latitude).HasColumnName("Latitude");
        this.Property(c => c.Coordinate.Longitude).HasColumnName("Longitude");

        this.Property(c => c.TimeZone).HasColumnName("timezone");

        this.Property(c => c.IsPublic).HasColumnName("isPublic");
        this.Property(c => c.IsActive).HasColumnName("active");

        this.Property(c => c.ParentCompanyId).HasColumnName("parent");

    }
}
4

1 に答える 1

0

Aron によって提供されたソリューションのフォローアップ。

この修正を実装した後、ClientAccount オブジェクトの Company を更新できないという問題にすぐに遭遇しました。モデルでは ClientAccount オブジェクトの CompanyId プロパティを更新できないため、これは理にかなっています。

外部キー プロパティがモデルに含まれています。次に、プロパティ名は、それが指すオブジェクトのキー プロパティ名と一致する必要があります。これにより、元の問題も解決しました。ただし、(既存の) Company モデルを変更する必要がありました。これは、Company クラスを既に使用している他のプロジェクトに影響を与えます。

変更:

私のモデルでは、CompanyId プロパティを追加し、Company id プロパティの名前を ID から CompanyId に変更しました (両方のプロパティ名を一致させるため)。

public class ClientAccount : IUserAccount
{
    public ClientAccount() { }

    ...

    public Nullable<int> CompanyId { get; set; }

    [DisplayName("Company")]
    public virtual Company Company { get; set; }

    ...
}

public class Company
{
    [Key]
    public int CompanyId { get; set; }

    public string Name { get; set; }

    ...

}

EntityTypeConfiguration で、新しい CompanyId プロパティを対応するデータベース列名にマップしましたが、Company マッピングを省略できます。

public class ClientAccountConfiguration : EntityTypeConfiguration<ClientAccount>
{
    public ClientAccountConfiguration()
        : base()
    {
        ...

        Property(p => p.CompanyId).HasColumnName("companyId");

        /*
        HasOptional(p => p.Company)
            .WithOptionalDependent()
            .Map(p => p.MapKey("companyId"));
        */

        ...
    }
}
于 2013-07-22T12:30:15.687 に答える