programing

EF Code First의 계산된 열

iphone6s 2023. 4. 12. 21:53
반응형

EF Code First의 계산된 열

데이터베이스에서 (행의 합계) - (행의 합계)로 계산되는 열이 데이터베이스에 하나 있어야 합니다.데이터베이스를 만들기 위해 코드 우선 모델을 사용하고 있습니다.

제 뜻은 다음과 같습니다.

public class Income {
      [Key]
      public int UserID { get; set; }
      public double inSum { get; set; }
}

public class Outcome {
      [Key]
      public int UserID { get; set; }
      public double outSum { get; set; }
}

public class FirstTable {
      [Key]
      public int UserID { get; set; }
      public double Sum { get; set; } 
      // This needs to be calculated by DB as 
      // ( Select sum(inSum) FROM Income WHERE UserID = this.UserID) 
      // - (Select sum(outSum) FROM Outcome WHERE UserID = this.UserID)
}

EF CodeFirst에서 이를 실현하려면 어떻게 해야 합니까?

데이터베이스 테이블에 계산된 열을 생성할 수 있습니다.EF 모델에서는 해당 속성에 주석을 달기만 하면 됩니다.DatabaseGenerated★★★★

[DatabaseGenerated(DatabaseGeneratedOption.Computed)]
public double Summ { get; private set; } 

또는 유연한 매핑을 사용하는 경우:

modelBuilder.Entity<Income>().Property(t => t.Summ)
    .HasDatabaseGeneratedOption(DatabaseGeneratedOption.Computed)

Matija Grcic의 제안과 코멘트에서 보듯이, 이 자산을 만드는 것은 좋은 아이디어입니다.private set어플리케이션 코드로 설정하고 싶지 않을 수도 있기 때문입니다.엔티티 프레임워크는 개인 설정자에 문제가 없습니다.

주의: EF의 경우.HasDatabaseGeneratedOption이 존재하지 않기 때문에 다음과 같이 NET Core를 사용해야 합니다.

modelBuilder.Entity<Income>().Property(t => t.Summ)
    .ValueGeneratedOnAddOrUpdate()

2019년 현재 EF core를 사용하면 다음과 같은 fluent API를 사용하여 열을 깔끔하게 계산할 수 있습니다.

「 」라고 합니다.DisplayName 속성을 할당하지.속성을 평소대로 정의해야 합니다.개인 속성 접근자를 사용하여 할당하지 않도록 할 수도 있습니다.

public class Person
{
    public int PersonId { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    // this will be computed
    public string DisplayName { get; private set; }
}

그런 다음 모델 작성기에서 열 정의로 해당 주소를 지정합니다.

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.Entity<Person>()
        .Property(p => p.DisplayName)
        // here is the computed query definition
        .HasComputedColumnSql("[LastName] + ', ' + [FirstName]");
}

상세한 것에 대하여는, MSDN 를 참조해 주세요.

public string ChargePointText { get; set; }

public class FirstTable 
{
    [Key]
    public int UserID { get; set; }

    [DatabaseGenerated(DatabaseGeneratedOption.Computed)]      
    public string Summ 
    {
        get { return /* do your sum here */ }
        private set { /* needed for EF */ }
    }
}

참고 자료:

EF6에서는 다음과 같이 계산된 속성을 무시하도록 매핑 설정을 구성할 수 있습니다.

모델의 get 속성에 대한 계산을 정의합니다.

public class Person
{
    // ...
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public string FullName => $"{FirstName} {LastName}";
}

그런 다음 모델 구성에서 무시하도록 설정합니다.

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    //...
    modelBuilder.Entity<Person>().Ignore(x => x.FullName)
}

한 가지 방법은 LINQ를 사용하는 것입니다.

var userID = 1; // your ID
var income = dataContext.Income.First(i => i.UserID == userID);
var outcome = dataContext.Outcome.First(o => o.UserID == userID);
var summ = income.inSumm - outcome.outSumm;

오브젝트 POCO 에서 실행할 수 .public class FirstTable좋은 디자인이 아니라고 생각하기 때문에 추천하고 싶지 않습니다.

다른 방법은 SQL 뷰를 사용하는 것입니다.Entity Framework를 사용하면 보기를 표처럼 읽을 수 있습니다.뷰 코드 내에서 계산이나 원하는 작업을 수행할 수 있습니다.다음과 같은 뷰를 생성하기만 하면 됩니다.

-- not tested
SELECT FirstTable.UserID, Income.inCome - Outcome.outCome
  FROM FirstTable INNER JOIN Income
           ON FirstTable.UserID = Income.UserID
       INNER JOIN Outcome
           ON FirstTable.UserID = Outcome.UserID

뷰 모델만 사용하면 됩니다.예를 들어 FirstTable 클래스를 DB 엔티티로 하는 것보다 FirstTable이라는 뷰 모델 클래스를 가지고 계산된 합계를 포함하는 이 클래스를 반환하는 데 사용되는 함수를 갖는 것이 더 낫지 않을까요?예를 들어 다음과 같은 클래스가 있습니다.

public class FirstTable {
  public int UserID { get; set; }
  public double Sum { get; set; }
 }

그런 다음 계산된 합계를 반환하는 함수를 사용할 수 있습니다.

public FirsTable GetNetSumByUserID(int UserId)
{
  double income = dbcontext.Income.Where(g => g.UserID == UserId).Select(f => f.inSum);
  double expenses = dbcontext.Outcome.Where(g => g.UserID == UserId).Select(f => f.outSum);
  double sum = (income - expense);
  FirstTable _FirsTable = new FirstTable{ UserID = UserId, Sum = sum};
  return _FirstTable;
}

기본적으로 SQL 뷰와 마찬가지로 @Linus가 언급했듯이 계산된 값을 데이터베이스에 유지하는 것은 좋지 않다고 생각합니다.그냥 몇 가지 생각일 뿐이야.

문자열 열 "Slug"을 가진 EF Code First 모델을 다른 문자열 열 "Name"에서 파생하려고 할 때 우연히 이 질문을 발견했습니다.제가 취한 접근법은 조금 달랐지만 잘 되었기 때문에 여기서 공유하겠습니다.

private string _name;

public string Name
{
    get { return _name; }
    set
    {
        _slug = value.ToUrlSlug(); // the magic happens here
        _name = value; // but don't forget to set your name too!
    }
}

public string Slug { get; private set; }

이 접근법의 좋은 점은 슬러그 세터를 노출시키지 않으면서 자동 슬러그 발생을 할 수 있다는 것입니다.ToUrlSlug() 메서드는 이 투고에서 중요한 부분이 아닙니다.필요한 작업을 하기 위해 그 대신 어떤 것도 사용할 수 있습니다.건배!

언급URL : https://stackoverflow.com/questions/15585330/calculated-column-in-ef-code-first

반응형