2012-03-08 4 views
2

다른 답변과 많은 기사를 살펴 봤지만이 간단한 부분은 여전히 ​​나를 잊어 버립니다. 저는 EF 코드 4.1을 처음 사용하고 있습니다 만, 더 쉽게 만들 수 있다면 새로운 버전으로 옮겨서 기쁩니다.EF 코드 첫 번째 : 외래 키 정의

public class ExpenseItemAccounting 
{ 
    [Key] 
    public String UniqueID_Accounting { get; set; } 
    public String ERLineID { get; set; } 
    public String ERNum { get; set; } 
    public String ItemNum { get; set; } 

우리가 볼 수 있듯이, 두 번째 테이블의 ERLineID 다음 ExpenseItems 한 관계로 많은이있는이 걸려

namespace Spend.Models 
{ 
    public class ExpenseItem 
    { 
     [Key] 
     public String UniqueID_ERLineID { get; set; } 
     public String ERNum { get; set; } 
     public String ItemNum { get; set; } 
     public String Parent_Expense_Item { get; set; } 
     public String Card_Number { get; set; } 
... 

여러 테이블 : 나는 주요 팩트 테이블과 같이가 처음에는 UniqueID_ErLineID에 조인하므로 일반적으로 사용하는 '규칙'은 작동하지 않습니다. 따라서 가상 ICollection을 사용해야합니다. 그러나이 필드를 링크로 지정하고 싶습니다. 이 작업을 수행하는 방법에 대한 도움을 주시면 감사하겠습니다.

추신. 현재 DB 필드의 이름을 바꿀 수 없습니다.

@LUKE :

언급 한 변경 사항을 적용했지만 의미가 있습니다. 그러나 나는 다음과 같은 오류가 발생합니다 :

System.Data.Entity.ModelConfiguration.ModelValidationException occurred 
    Message=One or more validation errors were detected during model generation: 

    System.Data.Edm.EdmAssociationType: : Multiplicity conflicts with the referential constraint in Role 'ExpenseItemAccounting_ExpenseItem_Target' in relationship 'ExpenseItemAccounting_ExpenseItem'. Because all of the properties in the Dependent Role are non-nullable, multiplicity of the Principal Role must be '1'. 
    System.Data.Edm.EdmAssociationEnd: : Multiplicity is not valid in Role 'ExpenseItemAccounting_ExpenseItem_Source' in relationship 'ExpenseItemAccounting_ExpenseItem'. Because the Dependent Role refers to the key properties, the upper bound of the multiplicity of the Dependent Role must be �1�. 

    Source=EntityFramework 
    StackTrace: 
     at System.Data.Entity.ModelConfiguration.Edm.EdmModelExtensions.ValidateAndSerializeCsdl(EdmModel model, XmlWriter writer) 
     at System.Data.Entity.DbModelBuilder.Build(DbProviderManifest providerManifest, DbProviderInfo providerInfo) 
     at System.Data.Entity.DbModelBuilder.Build(DbConnection providerConnection) 
     at System.Data.Entity.Internal.LazyInternalContext.CreateModel(LazyInternalContext internalContext) 
     at System.Data.Entity.Internal.RetryLazy`2.GetValue(TInput input) 
     at System.Data.Entity.Internal.LazyInternalContext.InitializeContext() 
     at System.Data.Entity.Internal.InternalContext.GetEntitySetAndBaseTypeForType(Type entityType) 
     at System.Data.Entity.Internal.Linq.InternalSet`1.Initialize() 
     at System.Data.Entity.Internal.Linq.InternalSet`1.get_InternalContext() 
     at System.Data.Entity.Infrastructure.DbQuery`1.System.Linq.IQueryable.get_Provider() 
     at System.Linq.Queryable.SelectMany[TSource,TCollection,TResult](IQueryable`1 source, Expression`1 collectionSelector, Expression`1 resultSelector) 
     at EmailClient.Prog.getData() in C:\MF\Dropbox\Dev_LN_Projects\04_QA\EmailClient\EmailClient\Prog.cs:line 172 
    InnerException: 

나는 다음과 같은 LINQ 쿼리하려고 할 때이 온 :

 var geee = (from e in db.ExpenseItems 
         from f in db.ExpenseItemFbtItems 
         where 
         e.Item_Transaction_Date.Value.Year == 2011 && 
         e.Item_Transaction_Date.Value.Month == 8 
         select new { A = e.UniqueID_ERLineID, B = f.ERLineID.First() }); 

실제로 e.ExpenseItemAccounting.ItemNum 또는 같은 말을 할 수있을 것으로 기대를 - 할 일을 이것을 달성하기 위해 뭔가를 ExpenseItem 정의에 넣어야합니까?

내 모델의 설정은 다음과 같습니다. base.OnModelCreating는 IntelliSense를 통해 나타나 나는 같은 결과를 도출하기 위하여없이 함께/그것을 시도했다 :

public class SpendDB : DbContext 
{ 
    public DbSet<ExpenseAttachment> ExpenseAttachments {get; set; } 
    public DbSet<ExpenseComment> ExpenseComments {get; set; } 
    public DbSet<ExpenseItemAccounting> ExpenseAccountings {get; set; } 
    public DbSet<ExpenseItemFbtItem> ExpenseItemFbtItems {get; set; } 
    public DbSet<ExpenseItem> ExpenseItems {get; set; } 
    public DbSet<ExpenseItemViolation> ExpenseItemViolations {get; set; } 

    protected override void OnModelCreating(DbModelBuilder modelBuilder) 
    { 
     base.OnModelCreating(modelBuilder); 
     modelBuilder.Entity<ExpenseItemAccounting>().HasOptional(e => e.ExpenseItem).WithMany().HasForeignKey(e => e.UniqueID_Accounting); 
    } 
} 

아마도 나는 ExpenseItem 정의에 가상 ICollection에 넣어해야합니까? 아니면 아마도 다른 방법일까요? 예를 들어 modelBuilder.Entity에는 선택적인 ExpenseItemAccounting이 있습니까? 그게 나에게 더 직관적 인 소리지만 나는 (분명히) 이렇게 잘하지 않으므로 소금 한 알씩 가져 가라.

다시 한번 감사

+0

에 ERLineID의 널 (NULL) 값을 변경한다. ModelBuilder를 .WithRequired로 변경하면이 문제를 해결할 수 있습니다. –

+0

또한 linq 쿼리에서 직접 참여하고 있습니다. 네비게이션 속성을 사용하여 db.ExpenseItemFbtItems ... select f.ExpenseItem ... f에서 예를 들어 탐색을 단순화 할 수 있습니다. ' –

답변

2

는이 작업을 수행합니다 : 다음

public class ExpenseItemAccounting 
{ 
    [Key] 
    public String UniqueID_Accounting { get; set; } 
    public ExpenseItem ExpenseItem{get;set;} 
    public String ERLineID { get; set; } 
    public String ERNum { get; set; } 
    public String ItemNum { get; set; } 
} 

당신의 모델 빌더를 사용

modelBuilder.Entity<ExpenseItemAccounting>().HasOptional(e => e.ExpenseItem).WithMany().HasForeignKey(e => e.UniqueID_Accounting); 

편집 :

은 다른의 컬렉션이 탐색 속성을 구성하려면 마지막으로 간단하게 추가 할 수 있습니다.

ExpenseItem이의를 ExpensItemAccounting 모든 자식의 목록을 가지고 있도록

modelBuilder.Entity<ExpenseItemAccounting>().HasOptional(e => e.ExpenseItem).WithMany(e=> e.ExpenseItems).HasForeignKey(e => e.UniqueID_Accounting); 

이 그것을 묶을 것입니다 당신은 또한 단수를 추가 할 수 있습니다, 다음과 같이

public class ExpenseItem 
{ 
     [Key] 
     public String UniqueID_ERLineID { get; set; } 
     public String ERNum { get; set; } 
     public String ItemNum { get; set; } 
     public String Parent_Expense_Item { get; set; } 
     public String Card_Number { get; set; } 
     public ICollection<ExpenseItemAccounting> ExpenseItemAccountings{ get; set; } 
} 

다음 모델 빌더 설정을 수정하여 그것을 배선

public class ExpenseItem 
    { 
      [Key] 
      public String UniqueID_ERLineID { get; set; } 
      public String ERNum { get; set; } 
      public String ItemNum { get; set; } 
      public String Card_Number { get; set; } 
      public ExpenseItemAccounting Parent_Expense_Item { get; set; } 
    } 

및 구성에 대한 모델 빌더를 사용하여 :

012이 버전은 더 의미 등을 만드는 경우

FK 레퍼런스가 네비게이션 속성뿐만 아니라 유선형으로되어 있기를 바란다면 별도의 문장에서이 작업을 수행해야하지만 좀 더 까다롭게 보일 것입니다.

탐색 속성에 대한 MSDN 페이지를 살펴보고 고급 물건의 좋은 예가 많이있는 modelBuilder를 사용하는 방법을 살펴보십시오. 솔루션의 http://msdn.microsoft.com/en-us/library/hh295843(v=vs.103).aspx

+0

안녕 루크 고마워. 여기서 완전히 설명 할 여지가 없습니다. 오류가 발생한 원래 질문에서 제 편집을보십시오. 더 이상의 코멘트는 좋을 것입니다! – Glinkot

+0

@Glinkot 네 절대적으로 관계를 양방향으로 만들 수 있습니다. 그냥 람다를 사용하여 withMany에서 컬렉션을 지정하면됩니다. 아쉽게 업데이트 내 게시물이 –

+0

그레이트 루크, 모든 세부 사항을 주셔서 감사합니다! – Glinkot

0

탐색 속성이 .WithOptional를 사용하고 DB가 아닌 널 (NULL) 키를 가지고 있기 때문에 당신이 여기 얻을 오류가 TRUE

관련 문제