gpt4 book ai didi

mysql - 通过反射确定泛型 TEntity 的哪些 PropertyInfo 是主键

转载 作者:行者123 更新时间:2023-11-29 07:36:57 26 4
gpt4 key购买 nike

我正在通过 EF Core 2.0 中的原始 SQL 命令编写 MySQL INSERT ... ON DUPLICATE KEY UPDATE 实现。我非常接近一个可行的解决方案,但我遇到的唯一问题是确定通过反射读取的哪些 PropertyInfo 是主键。在下面的 CreateUpdates() 方法中,如何从 columnProperties 中过滤出主键,使它们不属于更新 SQL 语句的一部分?

我试过使用 EntityFramework.PrimaryKey ,但我似乎无法让它与泛型一起工作 (TEntity)。

我已经包含了所有相关代码,但我在这个问题中关注的部分是最后一个方法 CreateUpdates() 中的TODO

private static void InsertOnDuplicateKeyUpdate<TEntity>(DbContext dbContext) where TEntity : class
{
var columnProperties = GetColumnPropertiesLessBaseEntityTimestamps<TEntity>();
var tableName = GetTableName<TEntity>();
var columns = string.Join(", ", columnProperties.Select(x => x.Name));
var values = CreateValues<TEntity>(columnProperties);
var updates = CreateUpdates(columnProperties);
var rawSqlString = "INSERT INTO " + tableName + " (" + columns + ") VALUES " + values +
" ON DUPLICATE KEY UPDATE " + updates;
dbContext.Set<TEntity>().FromSql(rawSqlString);
dbContext.SaveChanges();
}

private static string GetTableName<TEntity>()
{
return typeof(TEntity).Name.Pluralize().ToLower();
}

private static List<PropertyInfo> GetColumnPropertiesLessBaseEntityTimestamps<TEntity>()
{
return typeof(TEntity).GetProperties().Where(x =>
x.PropertyType.Namespace != "System.Collections.Generic" &&
!new List<string> {"CreatedDateUtc", "ModifiedDateUtc"}.Contains(x.Name)).ToList();
}

private static string CreateValues<TEntity>(IReadOnlyCollection<PropertyInfo> columnProperties)
{
return GetSeedRows<TEntity>().Select(row => CreateRowValues(columnProperties, row)).Aggregate("",
(current, rowValues) => current == "" ? rowValues : current + ", " + rowValues);
}

private static string CreateRowValues<TEntity>(IEnumerable<PropertyInfo> columnProperties, TEntity row)
{
return (from property in columnProperties
let value = row.GetType().GetProperty(property.Name).GetValue(row)
select WrapStringPropertyValueInSingleQuotes(property, value)).Aggregate("",
(current, value) => current == "" ? "(" + value : current + ", " + value) + ")";
}

private static object WrapStringPropertyValueInSingleQuotes(PropertyInfo property, object value)
{
if (property.PropertyType == typeof(string))
value = "'" + value + "'";
return value;
}

private static string CreateUpdates(IEnumerable<PropertyInfo> columnProperties)
{
//TODO: filter out primary keys from columnProperties
return columnProperties.Select(property => property.Name).Aggregate("", (current, column) => current == ""
? column + " = VALUES(" + column + ")"
: current + ", " + column + " = VALUES(" + column + ")");
}

最佳答案

在 ef-core 中,从映射模型中检索元数据变得更加容易。您可以通过以下行获取主键的 PropertyInfo:

var keyPropertyInfos = dbContext.Model.FindEntityType(typeof(TEntity))
.FindPrimaryKey()
.Properties
.Select(p => p.PropertyInfo);

顺便说一句,您可以通过将 FindPrimaryKey().Properties 替换为 GetProperties() 来获取所有(映射的)属性;

关于mysql - 通过反射确定泛型 TEntity 的哪些 PropertyInfo 是主键,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48360765/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com