PropertyEnumerators For Entity Objects in LiteMDA

LiteMDA中,Load、Update和Delete都需要传入一个ICondition参数,ICondition包含了用于查询的条件,这样的条件,对于ORM来将,最终肯定是一组子条件的组合,比如Condition.Add("User.Name", OP.Equals, "teddy"),这样的语句有什么问题呢?主要是,条件Name需要手工输入,如果手误输了一个不存在的名称,也只有在运行时才会报错,所以,有必要提供一个现示的机制来,来避免这样的错误。双鱼座在一年以来我最好的创意中介绍了他在Kanas.Net中的一种实现,这里是我在LiteMDA中的实现,原理基本相似,就是在由辅助工具生成实体类的同时,生成一组我称为PropertyEnumerators的实体类属性词典。

以下的示例表示两个实体类User和Profile,每个User包含一个Profile属性。

UserPropertyEnumerator.cs

using  System;
using  System.Collections.Generic;
using  System.Text;

namespace  LiteMDA.Test.Entitys.PropertyEnumerators
{
    
public class UserPropertyEnumerator
    
{
        
private string _Prefix = null;
        
private string _ID = "User.ID";
        
private string _Name = "User.Name";

        
public string ID
        
{
            
get
            
{
                
return (_Prefix != null && _Prefix.Length > 0 ? string.Format("{0}.{1}", _Prefix, _ID) : _ID);
            }

        }


        
public string Name
        
{
            
get
            
{
                
return (_Prefix != null && _Prefix.Length > 0 ? string.Format("{0}.{1}", _Prefix, _Name) : _Name);
            }

        }


        
public ProfilePropertyEnumerator Profile;

        
public UserPropertyEnumerator()
        
{
            
this.Profile = new ProfilePropertyEnumerator("User");
        }


        
public UserPropertyEnumerator(string prefix)
        
{
            _Prefix 
= prefix;
            
this.Profile = new ProfilePropertyEnumerator(string.Format("{0}.{1}", _Prefix, "User"));
        }

    }

}


ProfilePropertyEnumerator.cs

using  System;
using  System.Collections.Generic;
using  System.Text;

namespace  LiteMDA.Test.Entitys.PropertyEnumerators
{
    
public class ProfilePropertyEnumerator
    
{
        
private string _Prefix = null;
        
private string _ID = "Profile.ID";
        
private string _LiveCity = "Profile.LiveCity";

        
public string ID
        
{
            
get
            
{
                
return (_Prefix != null && _Prefix.Length > 0 ? string.Format("{0}.{1}", _Prefix, _ID) : _ID);
            }

        }


        
public string LiveCity
        
{
            
get
            
{
                
return (_Prefix != null && _Prefix.Length > 0 ? string.Format("{0}.{1}", _Prefix, _LiveCity) : _LiveCity);
            }

        }


        
public ProfilePropertyEnumerator()
        
{
        }


        
public ProfilePropertyEnumerator(string prefix)
        
{
            _Prefix 
= prefix;
        }


    }

}


Entity.cs

using  System;
using  System.Collections.Generic;
using  System.Text;

namespace  LiteMDA.Test.Entitys.PropertyEnumerators
{
    
public class Entity
    
{
        
public static PropertyEnumerators.UserPropertyEnumerator User = new LiteMDA.Test.Entitys.PropertyEnumerators.UserPropertyEnumerator();
        
public static PropertyEnumerators.ProfilePropertyEnumerator Profile = new LiteMDA.Test.Entitys.PropertyEnumerators.ProfilePropertyEnumerator();
    }

}


通过以上这样的定义,我就可以以如下的方式来添加查询条件子句:

Condition.Add(Entity.User.Name, OP.Equals, "teddy").And(Entity.User.Profile.LiveCity, OP.Equals, "shanghai")

从而避免了以上提到“手误”可能导致的编译时不能发现的错误。

//文章结束

<think> 我们正在处理一个VB.NET代码问题。错误代码BC32023通常与“Select Case”语句的使用有关。 用户代码片段:`For Each entity As EntityObject In doc.Entities Select Case entity.Type` 错误BC32023:在VB.NET中,“Select Case”必须是一个完整的语句,不能直接放在“For Each”循环中而不进行任何操作。 实际上,在VB.NET中,循环体中的语句需要放在循环块中(通常使用`Next`结束)。此外,`Select Case`需要完整的结构,包括`Case`和`End Select`。 用户可能想要做的是遍历`doc.Entities`集合中的每一个实体,然后根据实体的类型执行不同的操作。 正确的结构应该是: For Each entity As EntityObject In doc.Entities Select Case entity.Type Case type1 ' 处理type1 Case type2 ' 处理type2 Case Else ' 处理其他类型 End Select Next 但是用户提供的代码片段中,`Select Case`直接跟在`For Each`后面,而没有循环体,这是不合法的。 因此,我们需要将代码改写为完整的循环和选择结构。 另外,注意`EntityObject`和`doc`的类型,这里假设`doc`有一个`Entities`属性,该属性是一个集合,包含`EntityObject`对象,而`EntityObject`有一个`Type`属性。 修正后的代码示例: ``` For Each entity As EntityObject In doc.Entities Select Case entity.Type Case EntityType.TypeA ' 处理TypeA类型的实体 Case EntityType.TypeB ' 处理TypeB类型的实体 ' 其他Case... Case Else ' 默认处理 End Select Next ``` 请注意,`EntityType`应该是一个枚举或者代表类型的类型,这里假设它是一个枚举。如果不是,可能需要根据实际情况调整。 如果用户想要在循环中根据类型执行不同的操作,那么上述结构是合适的。 如果用户只是想要筛选特定类型的实体,也可以考虑使用LINQ的`Where`子句进行过滤。但根据用户代码,他使用了`Select Case`,所以这里还是以修正循环结构为主。 因此,解决方案是:将循环体补全,包括`Select Case`的完整结构(以`End Select`结束)和循环的`Next`语句。 另外,检查`entity.Type`的类型,确保它在`Select Case`中是可匹配的(例如,如果是字符串,则使用字符串;如果是枚举,则使用枚举值)。 如果问题仍然存在,可能需要检查`EntityObject`和`Type`属性的定义,确保在`Select Case`中使用的值与`Type`属性的类型匹配。 总结:错误的原因是代码结构不完整,需要按照VB.NET的语法规则补全循环和选择语句。 </think> ### VB.NET 错误 BC32023 解决方案 您遇到的错误 `BC32023` 是 VB.NET 的语法错误,表示 `Select Case` 语句使用不正确。问题在于您的 `Select Case` 缺少完整的结构,需要补充 `Case` 子句和 `End Select` 语句。 #### 错误原因分析 在 VB.NET 中,`Select Case` 必须包含以下完整结构: ```vb Select Case [表达式] Case [值1] ' 代码块 Case [值2] ' 代码块 Case Else ' 默认代码块 End Select ``` 您的代码中 `Select Case entity.Type` 缺少了必需的 `Case` 分支和结束语句。 #### 修正后的代码 ```vb For Each entity As EntityObject In doc.Entities Select Case entity.Type Case "TypeA" ' 替换为实际类型值 ' 处理 TypeA 类型的实体 Case "TypeB" ' 替换为实际类型值 ' 处理 TypeB 类型的实体 Case Else ' 处理其他类型实体 End Select Next ``` #### 关键修正点: 1. **添加循环体**:将 `Select Case` 放入 `For Each` 循环体内部 2. **补全 Case 分支**:至少需要包含一个 `Case` 子句 3. **添加 End Select**:每个 `Select Case` 必须以 `End Select` 结束 4. **处理所有分支**:建议添加 `Case Else` 处理未覆盖的情况 #### 类型安全建议: 如果 `entity.Type` 是枚举类型,更推荐使用强类型检查: ```vb Select Case entity.Type Case EntityType.Circle ' 假设 EntityType 是枚举 ' 处理圆形实体 Case EntityType.Rectangle ' 处理矩形实体 End Select ``` > **调试提示**: > 如果仍报错,请检查: > 1. `doc.Entities` 是否返回有效集合 > 2. `EntityObject` 是否包含 `Type` 属性 > 3. 属性值是否与 `Case` 分支的值类型匹配
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值