2014-06-20 5 views
1

OrmLite의 조인에 대한 데이터 액세스에서 래퍼를 만들었습니다.ServiceStack Ormlite Join Wrapper

지금은 예외를 받고 있어요 :

System.Exception : 표현이 하나의 컬럼 만 내 실체의

모두해야 한 BaseEntity의 기본 클래스. JoinType은 열, 선택 항목 및 조인 위치를 포함하는 외관 일뿐입니다.

public IEnumerable<TResultEntity> Join<TResultEntity>(IList<JoinType<BaseEntity, BaseEntity>> joins) 
     { 
      var result = new List<TResultEntity>(); 

      if (joins != null && joins.Any()) 
      { 
       var joinBuilder = new JoinSqlBuilder<T, BaseEntity>(); 

       foreach (var join in joins) 
       { 
        joinBuilder = joinBuilder.Join(join.LeftColumn, join.RightColumn, join.LeftSelection, join.RightSelection, join.LeftWhere, join.RightWhere); 
       } 

       var connection = this.DataConnection; 
       using (connection) 
       { 
        var joinSql = joinBuilder.SelectDistinct().ToSql(); 
        result = connection.SqlList<TResultEntity>(joinSql); 
       } 
      } 

      return result; 
     } 

을 같은 일을하고 목록이 작동하는 것 같다 않고 : 다음과 같이

내 래퍼입니다

public IEnumerable<TResultEntity> Join<TLeftTable1, TRightTable1, TLeftTable2, TRightTable2, TResultEntity>(
      JoinType<TLeftTable1, TRightTable1> join1, 
      JoinType<TLeftTable2, TRightTable2> join2) 
      where TLeftTable1 : BaseEntity 
      where TRightTable1 : BaseEntity 
      where TLeftTable2 : BaseEntity 
      where TRightTable2 : BaseEntity 

편집 - 나는 아래 전화 사용하여 테스트하고 있습니다 :

// Act 
       var join1 = new JoinType<AnswerEntity, UserSurveyStateEntity>(
       l => l.OwnerId, 
       r => r.UserId, 
       x => new { UserId = x.OwnerId, x.QuestionId, AnswerId = x.Id, x.AnswerValue }); 

       var join2 = new JoinType<SurveyEntity, UserSurveyStateEntity>(
       l => l.Id, 
       r => r.SurveyInstanceId, 
       x => new { SurveyId = x.Id, SurveyName = x.Name, x.StatusValue }, 
       null, 
       null, 
       x => x.StatusValue == (int)UserSurveyStatus.Complete); 

       var joins = new List<JoinType<BaseEntity, BaseEntity>>(); 
       joins.Add(join1.As<JoinType<BaseEntity, BaseEntity>>()); 
       joins.Add(join2.As<JoinType<BaseEntity, BaseEntity>>()); 

       var result = dataAccess.Join<AnswerEntity>(joins).ToList(); 
+0

어떤 라인이에 날려 않습니다

나는 다음과 같은 시험과 오류를 재현 할 수 있었다? – wbennett

+0

@wbennett joinBuilder = joinBuilder.Join (join.LeftColumn, join.RightColumn, join.LeftSelection, join.RightSelection, join.LeftWhere, join.RightWhere); – Bob

+0

ormlite 사투 사는 무엇입니까? – wbennett

답변

2

EDIT - 이제 유스 케이스를 보면 오류가 castin과 관련됩니다. g를 기본 유형으로, 빌더가 하나 이상의 열 선택기를 저장하여 구체적인 BaseEntity를 지정합니다. 추상 JoinType 클래스를 추가하고 JoinType 클래스를 수정하여 빌더에 대한 조인을 적용하십시오. 예를 들어

:

public class Entity 
    { 
     public string Id { get; set; } 
    } 
    public class Foo 
     : Entity 
    { 
     public string Value { get; set; } 
    } 

    public class Bar 
     : Entity 
    { 
     public string FooId { get; set; } 
     public string Value { get; set; } 
    } 

    public abstract class JoinType 
    { 
     public abstract JoinSqlBuilder<TNew, TBase> ApplyJoin<TNew, TBase>(
      JoinSqlBuilder<TNew, TBase> bldr); 
    } 

    public class JoinType<TSource, TTarget> 
     : JoinType 
    { 
     private Expression<Func<TSource, object>> _sourceColumn; 
     private Expression<Func<TTarget, object>> _destinationColumn; 
     private Expression<Func<TSource, object>> _sourceTableColumnSelection; 
     private Expression<Func<TTarget, object>> _destinationTableColumnSelection; 
     private Expression<Func<TSource, bool>> _sourceWhere; 
     private Expression<Func<TTarget, bool>> _destinationWhere; 

     public JoinType(Expression<Func<TSource, object>> sourceColumn, 
      Expression<Func<TTarget, object>> destinationColumn, 
      Expression<Func<TSource, object>> 
       sourceTableColumnSelection = null, 
      Expression<Func<TTarget, object>> 
       destinationTableColumnSelection = null, 
      Expression<Func<TSource, bool>> sourceWhere = null, 
      Expression<Func<TTarget, bool>> destinationWhere = 
       null) 
     { 
      this._sourceColumn = sourceColumn; 
      this._destinationColumn = destinationColumn; 
      this._sourceTableColumnSelection = sourceTableColumnSelection; 
      this._destinationTableColumnSelection = 
       destinationTableColumnSelection; 
      this._sourceWhere = sourceWhere; 
      this._destinationWhere = destinationWhere; 
     } 

     public override JoinSqlBuilder<TNew, TBase> ApplyJoin<TNew, TBase>(
      JoinSqlBuilder<TNew, TBase> bldr) 
     { 
      bldr.Join(_sourceColumn, 
       _destinationColumn, 
       _sourceTableColumnSelection, 
       _destinationTableColumnSelection, 
       _sourceWhere, 
       _destinationWhere); 

      return bldr; 
     } 
    } 

    public class FooBar 
    { 
     [References(typeof(Foo))] 
     public string FooId { get; set; } 
     [References(typeof(Bar))] 
     public string BarId { get; set; } 
     [References(typeof(Foo))] 
     public string FooValue { get; set; } 
     [References(typeof(Bar))] 
     public string BarValue { get; set; } 
    } 

    /* 
    This join accomplishes the same thing, but just returns the SQL as a string. 
    */ 
    public string Join<TResultEntity,TBase>(IList<JoinType>joins) 
    { 
     var result = new List<TResultEntity>(); 

     if (joins != null && joins.Any()) 
     { 
      var joinBuilder = new JoinSqlBuilder<TResultEntity, TBase>(); 

      foreach (var joinType in joins) 
      { 
       //call the apply join, and the join type will know the valid types 
       joinBuilder = joinType.ApplyJoin(joinBuilder); 
      } 

      return joinBuilder.SelectDistinct().ToSql(); 
     } 

     return null; 
    } 

    [TestMethod] 
    public void TestMethod1() 
    { 
     OrmLiteConfig.DialectProvider = SqlServerDialect.Provider; 

     var joins = new List<JoinType>(); 

     var jointype1 = new JoinType<Bar, FooBar>(
      bar => bar.Id, 
      bar => bar.BarId, 
      bar => new { BarId = bar.Id, BarValue = bar.Value } 
      ); 
     joins.Add(jointype1); 
     var joinType2 = new JoinType<Foo, FooBar>(
      foo => foo.Id, 
      bar => bar.FooId, 
      foo => new { FooId = foo.Id, FooValue = foo.Value} 
      ); 
     joins.Add(joinType2); 

     var str = Join<FooBar, Bar>(joins); 
    } 

올드 대답 -이 오류는 사용자의 선택 join.LeftColumn 또는 join.RightColumn 포함하는 두 선택기에 의해 발생하는 오류

에 여전히 관련. 하나만 포함해야합니다.

public class Entity 
    { 
     public string Id { get; set; } 
    } 
    public class Foo 
     : Entity 
    { 
     public string Value { get; set; } 
    } 

    public class Bar 
     : Entity 
    { 
     public string FooId { get; set; } 
     public string Value { get; set; } 
    } 

    public class FooBar 
    { 
     [References(typeof(Foo))] 
     public string FooId { get; set; } 
     [References(typeof(Bar))] 
     public string BarId { get; set; } 
     [References(typeof(Foo))] 
     public string FooValue { get; set; } 
     [References(typeof(Bar))] 
     public string BarValue { get; set; } 
    } 

    [TestMethod] 
    public void TestMethod1() 
    { 
     OrmLiteConfig.DialectProvider = SqlServerDialect.Provider; 
     var bldr = new JoinSqlBuilder<FooBar,Bar>(); 
     bldr = bldr.Join<FooBar, Bar>(
      bar => bar.BarId, 
      bar => new { Id1 = bar.Id, Id2 = bar.Id},//<-- this should only contain a single member 
      bar => new { BarId =bar.BarId }, 
      bar => new { BarId = bar.Id, BarValue = bar.Value}, 
      bar => bar.BarId != null, 
      bar => bar.Id != null 
      ); 

     var str = bldr.SelectDistinct().ToSql(); 
    } 
+0

동일한 소스 및 대상을 가진 조인 목록의 경우이 방법이 유용합니다. 내가 다른 목표와 출처를 가지고 있다면 그것은 효과가 없을 것이다. 예 : UserEntity + QuestionEntity & QuestionEntity + AnswerEntity입니다. – Bob

+0

좋아. 왜 당신은 그 예외를 받고 있는지에 대한 내 수정 된 답변을 참조하십시오. 처음 두 매개 변수에 두 개 이상의 멤버식이 포함되어 있지 않은지 확인하십시오. – wbennett

+0

필자는 어떻게 든 내 엔티티를 기본 클래스로 다시 캐스팅했기 때문이라고 생각합니다. – Bob

관련 문제