Soru Varlık Çerçevesi - sütunları nasıl alabilirim?


Sütun adlarının, türlerinin ve sütunun Entity Framework'teki tablo nesnesinin bir PK olup olmadığını öğrenmek istiyorum.

Bunu C # (4.0) 'da (ideal olarak genel olarak) nasıl yaparım?

Kazanan cevap, verimli ve en önemlisi genel olarak yapan bir cevap olacaktır.


17
2018-05-19 09:33


Menşei


Hangi amaçla ve hangi bağlamda? Demek istediğim, EF ile Varlıklar var, o zaman neden örnek mankenlerinizi yansıtmıyorsunuz ve orada olabilecekleri kurallara göre adlandırarak PK'leri bulmuyorsunuz? - sharp johnny
Gönderi neden reddedildi? Eğer bunun kötü bir soru olduğunu düşünüyorsanız - lütfen yorum yapın ve yazıyı defize etmek yerine daha fazlasını açıklayacağım. - Dan B
@johnny Evet - İfadeleri kullanarak bir deyim oluşturmaya çalışıyorum. Dinamik olarak oluşturulmuş lambda ifadeleri içeren her bir sütun için bir .contains ekleyen tümcenin dinamik olarak oluşturulduğunu biliyorum. Ancak, özellik adlarının varsayılan bir koleksiyonunu oluşturmak ve alan adlarının özel geçişini doğrulamak için tablo özelliklerine ihtiyacım var. Diğer her şey şu ana kadar gayet iyi çalışıyor - sadece EF tablo sütunlarını eksik - Dan B
@Femaref - lütfen gönderinin düzenlenmesi için nedenini açıklayın? - Dan B
Düzenlenen kısım, eldeki soruna hiçbir şey eklemedi ve genel olarak, yine de SO üzerinde çattı. - Femaref


Cevaplar:


Anladım - linq tabanlı yansıma sorgusu kullandım:

IEnumerable<FieldList> properties = from p in typeof(T).GetProperties()
                                    where (from a in p.GetCustomAttributes(false)
                                    where a is EdmScalarPropertyAttribute   
                                    select true).FirstOrDefault()

Sıralama! Önerileriniz için teşekkürler.

FYI - LINQ, dinamik lambda ifadeleri kullanarak, örn. varsayılan olarak tüm sütunları otomatik olarak arayacak olan arama. Ancak, doğrulamak için sütun isimlerine de ihtiyacım vardı çünkü bunun geçersiz kılınmasına izin vereceğim ve bu çağrılar, girdileri güvenilir olmayan javascript ajax postası üzerinden yapılacaktır - bu nedenle sütun adlarını doğrulamak gerekir.

Yukarıdaki sonuçları, FieldName, FieldType, PrimaryKey adlı özelliklere sahip özel bir nesneye yerleştirmek için kullandım. Ta daaa.

İle daha da özelleştirin

IEnumerable<FieldList> properties = from p in typeof(T).GetProperties()
                                    where (from a in p.GetCustomAttributes(false)
                                    where a is EdmScalarPropertyAttribute
                                    select true).FirstOrDefault()
                                    select new FieldList
                                    {
                                       FieldName = p.Name,
                                       FieldType = p.PropertyType,
                                       FieldPK = p.GetCustomAttributes(false).Where(a => a is EdmScalarPropertyAttribute && ((EdmScalarPropertyAttribute)a).EntityKeyProperty).Count() > 0
                                     };    

10
2018-05-22 12:04



yansıma olmayan yollar? - Brady Moritz
@boomhauer yansıma yöntemi için aşağıdaki cevaba bakınız - Pete_ch


Sadece sütun isimleri istiyorsanız, en iyi cevabı aldım:
var properties = (from t in typeof(YourTableName).GetProperties() select t.Name).ToList(); var name= properties[0];


7
2018-05-28 10:05



Yetene sahip değilim ya da sana 100 dolar veririm. - Muhammad Ashikuzzaman


Yansıma kullanmak istemiyorsanız, cevaba bakınız İşte. Aşağıdaki varlık adınızı varlık adınızla değiştirin

var cols = from meta in ctx.MetadataWorkspace.GetItems(DataSpace.CSpace)
                       .Where(m=> m.BuiltInTypeKind==BuiltInTypeKind.EntityType)
                    from p in (meta as EntityType).Properties
                       .Where(p => p.DeclaringType.Name == "EntityName")
                   select new
                      {
                       PropertyName = p.Name,
                       TypeUsageName = p.TypeUsage.EdmType.Name, //type name
                       Documentation = p.Documentation != null ?               
                                       p.Documentation.LongDescription : null //if primary key
        };

4
2018-06-26 04:43



Ne ctx ve nasıl bir tanıtıcı alabilirim? Önce Model veya Datbase için mi, çünkü önce Code'u kullanıyorum - Alan Macdonald
3.5'de objectcontext örneği, daha sonraki EF sürümlerinde kullandığınız dbcontext örneğini kullanır. örnek var ctx = yeni MyEntities kullanarak .... - Pete_ch
Ben 4.5 Net Kodu FIrst ve DBContext MetadataWorkspace özelliği yok - Alan Macdonald
dbcontext nesnesine bağlam dönüştürür: ((IObjectContextAdapter) dbContext) .ObjectContext; ya da gör stackoverflow.com/questions/8059900/... - Pete_ch
Teşekkürler bu çalıştıran var bağdaştırıcı = (IObjectContextAdapter); var childNavProperties = adapter.ObjectContext.MetadataWorkspace.GetItems (DataSpace.CSpace) .Where (öğe => item.BuiltInTypeKind == BuiltInTypeKind.EntityType) .SelectMany (öğe => ((EntityType) öğesi) .NavigationProperties) - Alan Macdonald


Sizin için bir kod örneğim yok, ancak doğru yönde işaret ettiğinizde Sql Yönetim Nesneleri'ni (SMO) kullanmayı isteyebilirsiniz; Sql Server örneği için bir nesne hiyerarşisi almak için bunu kullanabilirsiniz, daha sonra istediğiniz bilgileri toplayabilir ve seçebilirsiniz.

Programlamaya başlamanız için bu eğitici setine bir göz atın. http://www.codeproject.com/KB/database/SMO_Tutorial_1.aspx http://www.codeproject.com/KB/database/SMO_Tutorial_2.aspx


0
2018-05-19 10:04



Hayır Hayır - ef tablosu tablolarını değil koddaki ef tablosu nesnelerini incelemek istiyorum. Yani ef şemasına bir tablo eklediğinizde oluşturulan ef sınıfının özellik adlarına ihtiyacım var - Dan B
@Dan B - "admin" metni kaldırdı Ready, steady....GO! Thanks, Dan.. Gönderi bu değişimle anlamının bir kısmını nasıl kaybetti? - Yakimych
@Yakimych - benim hatam o zaman - daha fazla olduğunu farz ettim. Sanırım içinde bir duruşum vardı ve sonra onu çıkardım ama içeride olduğunu düşündüm. Bunu nasıl buldun? Yazmamamız gereken şeyleri bilmeye çok hevesliyim, çünkü bu çok kısa bir yazı için hiçbir şekilde zararlı görünmüyor. Şimdi yanlış yorumumu kaldırdım. Gönderiyi kimin oy verdiğini söyleyebilir misin? - Dan B
@Dan B - Düzenlediğini söylediği yere tıklarsanız, düzenleme geçmişini görebilirsiniz. Ne değiştiğini gösterir. - Tridus
@Dan B - Ayrıca, herhangi bir nedenle yayınınızın düzenlenmesini kabul etmezseniz, geri alabilirsiniz. Ve hayır, yazılarınızı kimin aldığını veya düşürdüğünü göremezsiniz. Ancak, size katılıyorum, bu nedenle, bir downvote yapan kullanıcının nedenini açıklayan bir yorum bırakması gerekir. - Yakimych


DB First veya Model First kullanıyorsanız, bir metin düzenleyicisinde oluşturulan .edmx dosyasını açın. Bu sadece bir XML dosyası ve ihtiyacınız olan her şeyi içerir. İşte benim bir modelimden bir örnek. Oracle'ın EF sürücüsünü kullandığımı unutmayın, böylece sizinki aynı görünmeyecektir (ancak oldukça yakın olmalıdır).

        <EntityType Adı = "STRATEGIC_PLAN">
          <Anahtar>
            <PropertyRef Name = "Kimlik" />
          </ Anahtar>
          <Property Type = "Decimal" Name = "Id" Nullable = "false" Precision = "8" Scale = "0" notu: StoreGeneratedPattern = "Hiçbiri" />
          <Property Type = "Decimal" Name = "CreatedById" Nullable = "false" Precision = "8" Scale = "0" />
          <Özellik Türü = "DateTime" Name = "CreatedDate" Nullable = "false" />
          <Property Type = "Decimal" Name = "DepartmentId" Nullable = "false" Precision = "4" Scale = "0" />
          <Özellik Türü = "Dize" Ad = "Name_E" Nullable = "false" MaxLength = "2000" FixedLength = "false" Unicode = "false" />
          <Özellik Türü = "Dize" Ad = "Name_F" MaxLength = "2000" FixedLength = "false" Unicode = "false" />
          <Property Type = "Decimal" Name = "UpdatedById" Precision = "8" Scale = "0" />
          <Özellik Türü = "DateTime" Name = "UpdatedDate" />
          <Property Type = "DateTime" Name = "Timestamp" Nullable = "false" Precision = "6" notu: StoreGeneratedPattern = "Hesaplanan" />
          <NavigationProperty Name = "AnnualPlans" İlişkisi = "StrategicPlanningModel.R_51213" FromRole = "STRATEGIC_PLAN" Yapılacaklar = "STRAT_ANNUAL_PLAN" />
          <NavigationProperty Name = "Department" İlişkisi = "StrategicPlanningModel.R_51212" FromRole = "STRATEGIC_PLAN" ToRole = "DEPARTMENT" />
          <NavigationProperty Name = "CreatedBy" İlişkisi = "StrategicPlanningModel.R_51210" FromRole = "STRATEGIC_PLAN" ToRole = "PERSONEL" />
          <NavigationProperty Name = "UpdatedBy" İlişkisi = "StrategicPlanningModel.R_51211" FromRole = "STRATEGIC_PLAN" ToRole = "PERSONEL" />
          <Özellik Türü = "Dize" Ad = "Desc_E" MaxLength = "2000" FixedLength = "false" Unicode = "false" />
          <Özellik Türü = "Dize" Ad = "Desc_F" MaxLength = "2000" FixedLength = "false" Unicode = "false" />
          <NavigationProperty Name = "Goals" Relationship = "StrategicPlanningModel.R_51219" FromRole = "STRATEGIC_PLAN" Yapılacaklar = "STRATEGIC_PLAN_GOAL" />
        </ EntityType>

Dosyayı ayrıştırmak ve ihtiyacınız olanı almak için bir XML ayrıştırıcısı kullanabilirsiniz. .Edmx dosyası hem varlıklar hem de SQL tabloları hakkında veri içerir, bu yüzden istediğiniz şeyi elde etmek için doğru parçayı aldığınızdan emin olmanız gerekir.


0
2018-05-19 11:37



Bu harika - kesinlikle buna geri döneceğim ama hala 4.0 yaşıyorum ve ilk önce (henüz) normal EF 4.0'a bakmıyorum. - Dan B
O zaman işe yarayacak. :) Kod İlk işe yaramazsa, ilk önce kodda edmx dosyası bulunmadığı durumdur. - Tridus
GÜZEL! Üzgünüm - öğle yemeğinden sonra uykulu LOL Bir göz atacağım ve nasıl aldığımı bileceğim - CHEERS! - Dan B


Birisi hala görünüyorsa, İşte ben yaptım. Bu, bir tür alır ve fiziksel sütun adları ve özelliklerini döndüren DBContext için bir uzantısı yöntemidir.

Bu, fiziksel sütunlar listesi almak için nesne bağlamını kullanır, daha sonra, her sütunu kendi özelliği ile eşlemek için "PreferredName" meta veri özelliğini kullanır.

Nesne bağlamını kullandığından, bir veritabanı bağlantısı başlatır, bu nedenle ilk çalışma, içeriğin karmaşıklığına bağlı olarak yavaş olacaktır.

public static IDictionary<String, PropertyInfo> GetTableColumns(this DbContext ctx, Type entityType)
{
    ObjectContext octx = (ctx as IObjectContextAdapter).ObjectContext;
    EntityType storageEntityType = octx.MetadataWorkspace.GetItems(DataSpace.SSpace)
        .Where(x => x.BuiltInTypeKind == BuiltInTypeKind.EntityType).OfType<EntityType>()
        .Single(x => x.Name == entityType.Name);

    var columnNames = storageEntityType.Properties.ToDictionary(x => x.Name,
        y => y.MetadataProperties.FirstOrDefault(x => x.Name == "PreferredName")?.Value as string ?? y.Name);

    return storageEntityType.Properties.Select((elm, index) =>
            new {elm.Name, Property = entityType.GetProperty(columnNames[elm.Name])})
        .ToDictionary(x => x.Name, x => x.Property);
}

Bunu kullanmak için, sadece bir yardımcı statik sınıf oluşturun ve yukarıdaki işlevi ekleyin; o zaman arama kadar basit

var tabCols = context.GetTableColumns(typeof(EntityType));

0
2017-09-18 02:58





typeof(TableName).GetProperties().Select(x => x.Name).ToList();

0
2017-08-10 03:33