2016-11-10 2 views
1

몇 년 동안 사용해오고 있지만 일종의 순환 참조 문제로 인해 속도가 느려지는 Entity Framework (버전 5) 구현에 대해 다음 데이터베이스 구조가 있습니다. 엔티티 프레임 워크가 지연되지 않습니다. 추가 FK 컬렉션을

[Table("Sensors", Schema = "Ems")] 
public class Sensor 
{ 
    public Sensor() 
    { 
     SensorSamples = new List<SensorSample>() as ICollection<SensorSample>; 
    } 

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

    [Required, MaxLength(128)] 
    public string Name { get; set; } 

    [MaxLength(256)] 
    public string Description { get; set; } 

    [MaxLength(128)] 
    public string Location { get; set; } 

    [Required] 
    [MaxLength(15)] 
    public string IPAddress { get; set; } 

    [Required] 
    public int Port { get; set; } 

    [Required] 
    public bool Enabled { get; set; } 

    [Required, ForeignKey("Type")] 
    public int SensorTypeId { get; set; } 

    public virtual SensorType Type { get; set; } 

    [Required, ForeignKey("Network")] 
    public int SensorNetworkId { get; set; } 

    public virtual SensorNetwork Network { get; set; } 

    public virtual ICollection<SensorSample> SensorSamples { get; set; } 
} 

[Table("SensorSamples", Schema = "Ems")] 
public class SensorSample 
{ 
    public SensorSample() 
    { 
     SampleData = new List<SampleData>() as ICollection<SampleData>; 
    } 

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

    [Required, ForeignKey("Sensor")] 
    public int SensorId { get; set; } 

    public virtual Sensor Sensor { get; set; } 

    [Required] 
    public DateTime SampleTime { get; set; } 

    [Required] 
    public virtual ICollection<SampleData> SampleData { get; set; } 
} 

[Table("SampleData", Schema = "Ems")] 
public class SampleData 
{ 
    public SampleData() 
    { 
    } 

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

    [Required, ForeignKey("DataType")] 
    public int SampleDataTypeId { get; set; } 

    public virtual SampleDataType DataType { get; set; } 

    [Required, ForeignKey("Unit")] 
    public int SampleUnitId { get; set; } 

    public virtual SampleUnit Unit { get; set; } 

    [Required, ForeignKey("Sample")] 
    public int SensorSampleId { get; set; } 

    public virtual SensorSample Sample { get; set; } 

    [MaxLength(128)] 
    public string Value { get; set; } 
} 

나는 다음과 같은 코드를 사용하여 새 SensorSample를 추가

, 그것은 그것이 SensorSample를 인스턴스화하기 때문에 추가 할 첫 번째 영원히 취하고 Sensor 인스턴스에서 Samples 컬렉션에 추가합니다.

Sensor sensor = GetSensor(1); 
SensorSample sample = new SensorSample(); 
sample.SampleTime = d.Timestamp; 
sample.SensorId = sensor.Id; 
sensor.SensorSamples.Add(sample); 

어떻게하면 SensorSamples 기존의 enitire 수집을 인스턴스화하지 않고 SensorSensorSamples에 샘플을 추가 할 수 있습니까? 현재 AutoDetectChangesEnabled을 false로 설정하고 을 SaveChanges 직전까지 지연합니다. 이것은 아무런 차이가 없습니다. 나는 LazyLoading을 끄지 않았지만, 나는이 상황에서 기대했던 것처럼 발로 차있는 것처럼 보이지 않는다. 공개 리스너가없는 생성자를 갖는 것과 같은 LazyLoading에 대한 모든 요구 사항이 충족된다고 생각합니다. 내가 놓친 게 있니? 왜 이런 일이 일어나고 있는거야? 감사.

+0

왜 게으른 로딩을 끄지 않았습니까 ('LazyLoadingEnabled = false')? –

답변

1

나는 왜 이런 일이 벌어지고 있는지에 대해 매우 좋은 생각을 가지고있다. EF가 데이터베이스에서 무언가를로드 할 때, 당신의 타입을 반환하지 않고 대신에 당신의 타입을 리턴하는 클래스를 리턴한다. 이 클래스에 EF가 관계를 추론 할 수있는 가상 속성이있는 경우이 클래스는 가상 속성을 구현하므로 액세스시 저장소에서 관련 개체를로드합니다. 이러한 작업은 점점 더 많은 외래 키가 인스턴스와 연관되어 있기 때문에 상당히 길어질 수 있습니다.

이 문제를 피하려면 센서 샘플 인스턴스를 만들고 비즈니스 모델과 저장소 모델을 매핑하고 샘플을 센서와 연결하는 외래 키를 설정하십시오. 이 작업이 완료되면 샘플을 DbContext의 적절한 DbSet에 추가하고 변경 내용을 저장합니다.

그것은는 다음과 같다 :

var sample = new SensorSample(); 

.. Map properties and values from business to storage model 

//Map the sensor foreign key for this sample 
sample.SensorId = sensor.Id; 

context.SensorSamples.Add(sample); 
context.SaveChanges(); 

(!) 참고 : 당신이 결과 세트가 잘 묶여 있는지 알지 못한다면

은 EF의 게으른 가상 수집 기능을 사용 자제 마십시오.

+0

추천 해 주셔서 감사합니다. 이제'DbContext'의'SensorSamples'''DbSet'에 직접 추가하는 대신'Sensor' 컬렉션을 통해 원래'SensorSample'을 왜 추가했는지 확신 할 수 없습니다. 나는 당신이 돌아가서 3 년 된 코드를 분석 할 때 일어나는 일이라고 생각합니다. 그것은 분명히 문제를 해결했습니다. – Psyfun

+0

나는 그 사람이 어떻게 느끼는지 정확히 알고있다. @ Psyfun –

관련 문제