XSLT存档  

不及格的程序员-八神

 查看分类:  ASP.NET XML/XSLT JavaScripT   我的MSN空间Blog
随笔 - 878,  文章 - 0,  评论 - 1190,  阅读 - 34万
< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

I've created an EDMX object from a database I'm programming against.

I need to get input from a user and save it to a row in the database table. The problem is that I need to limit the length of input strings to the width of the corresponding VARCHAR column in the database.

When I browse the model, I can clearly see in the properties window that the model knows the max length of the string, but I don't know how to access this data in code.

If I want to write something like this:

Entities entities = new Entities();
myTable = entities.myTable.First();
if (userInput.length > myTable.columnA.MaxLength)
{
    // tell the user that the input is too long.
}
else
{
    myTable.columnA = userInput;
}

How do I write it?

Update: I would like to point out that the IObjectContextAdapater mentioned in the answers below is in the System.Data.Entity.Infrastructure namespace.

shareeditflag
 
    
   
I'm surprised by the low number of views on this question. Thanks very much for the helpful answers; I might have never figured it out on my own. – Daniel Allen Langdon Nov 20 '14 at 20:35

2 Answers

Here are two methods by which you can read the meta data:

int? GetMaxLength(DbContext context, string tableName, string propertyName)
{
    var oc = ((IObjectContextAdapter)context).ObjectContext;

    return oc.MetadataWorkspace.GetItems(DataSpace.CSpace).OfType<EntityType>()
             .Where(et => et.Name == tableName)
             .SelectMany(et => et.Properties.Where(p => p.Name == propertyName))
             .Select (p => p.MaxLength)
             .FirstOrDefault();
}

int? GetMaxLength<T>(DbContext context, Expression<Func<T, object>> property)
{
    var memberExpression = (MemberExpression)property.Body;
    string propertyName = memberExpression.Member.Name;
    return GetMaxLength(context, typeof(T).Name, propertyName);
}

So you can either enter the table name and property name, or an expression that specifies the property you're interested in.

Another approach could be to create a MetaData class and use the MaxLength attribute.

shareeditflag
 
    
   
I'm confused. I thought that the EDMX entities is an ObjectContext, which has nothing to do with DbContext. – Daniel Allen Langdon Nov 19 '14 at 22:19
1  
   
Not necessarily. You'd have to check. If it is an ObjectContext you don't need this ((IObjectContextAdapter)context).ObjectContext part. – Gert Arnold Nov 19 '14 at 22:21
    
   
I did check and I see that it's a DbContext. To be honest, I have heard of DbContext, but I haven't read up on all the new features of the new Entity Framework versions, so this one got past me. Wow, there is so much keeping up to do in the .net world! – Daniel Allen Langdon Nov 19 '14 at 22:24
    
   
The function GetItems returns an enumeration of 393 items. However, the OfType<myTable> function, where myTable is a model of a SQL table, returns an empty enumeration. – Daniel Allen Langdon Nov 19 '14 at 22:56
2  
   
You should leave EntityType there, it's an EF class. – Gert Arnold Nov 19 '14 at 23:05

It's not very pretty; reading edmx properties at runtime is not something Microsoft exposed easily or documented well (or in some cases, at all). context is your DBContext.

var objectContext = ((IObjectContextAdapter)context).ObjectContext;
var entityType = objectContext.MetadataWorkspace.GetItems<EntityType>(DataSpace.CSpace).Where(e => e.Name == "your entity name").First();
var facets = entityType.Properties["your property name"].TypeUsage.Facets;

facets will look something like this, so you'll need to look for the MaxLength Name(may not exist, depending on the underlying field type) and get the Value:

Count = 5
    [0]: Nullable=false
    [1]: DefaultValue=null
    [2]: MaxLength=250
    [3]: Unicode=false
    [4]: FixedLength=false

 


 
 Retrieving Entity Framework Entity Property MaxLength Value from EDMX

I have an auto-generated entity framework Entity Data Model Designer File (edmx).  And while I am using Data Annotations for validation purposes, there are times when retrieving the maxlength of an entity property programmatically would be very useful. 

image

In some cases, I may want to simply truncate the value, rather than throw an error if the maxlength of a property is exceeded.  Or I may want to surface the maxlength property to the client for client-side validation purposes.

It turns out to be a simple query, but it took me a while to find it.  You will need to reference the following libraries:

using System.Data.Objects.DataClasses; 
using System.Data.Metadata.Edm;

This is the method to retrieve the MaxLength property.  Please note that you may get an exception if the property does not have a MaxLength property specified.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
public static int? GetMaxLength(this EntityObject entityObject, string entityProperty)
{
CATDBEntities _context = new CATDBEntities();
int? result = null;
using (_context)
{
    var q = from meta in _context.MetadataWorkspace.GetItems(DataSpace.CSpace)
                        .Where(m => m.BuiltInTypeKind == BuiltInTypeKind.EntityType)
            from p in (meta as EntityType).Properties
                .Where(p => p.DeclaringType.Name == entityObject.GetType().Name
                    && p.Name == entityProperty
                    && p.TypeUsage.EdmType.Name == "String")
            select p;
 
    var queryResult = from meta in _context.MetadataWorkspace.GetItems(DataSpace.CSpace)
                        .Where(m => m.BuiltInTypeKind == BuiltInTypeKind.EntityType)
                        from p in (meta as EntityType).Properties
                            .Where(p => p.DeclaringType.Name == entityObject.GetType().Name
                                && p.Name == entityProperty
                                && p.TypeUsage.EdmType.Name == "String")
                        select p.TypeUsage.Facets["MaxLength"].Value;
    if (queryResult.Count() > 0)
    {
        result = Convert.ToInt32(queryResult.First());
    }
}
return result;
}

  

 

To call this method, simply instantiate the entity object and pass in the proper parameters:

project _project = new project(); 
            int? maxLength = DataAnnotation.GetMaxLength(_project, "project_name");

posted on   不及格的程序员-八神  阅读(18)  评论(0编辑  收藏  举报
编辑推荐:
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
阅读排行:
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· .NET周刊【3月第1期 2025-03-02】
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
历史上的今天:
2015-12-08 Objective C运行时(runtime)
2010-12-08 MonoDevelop/MonoTouch SDK开发iOS程序体验!
点击右上角即可分享
微信分享提示